Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*-----------TEMPLATE---------------*/
- #include <algorithm>
- #include <cassert>
- #include <cctype>
- #include <cmath>
- #include <cstdarg>
- #include <cstdlib>
- #include <cstdio>
- #include <cstring>
- #include <ctime>
- #include <functional>
- #include <iterator>
- #include <map>
- #include <numeric>
- #include <set>
- #include <string>
- #include <vector>
- using namespace std;
- #define all(x) (x).begin(),(x).end()
- #define eprintf(...) {fprintf(stderr, __VA_ARGS__); fflush(stderr);}
- #define forab(i, a, b) for (int i = (int)(a); i < ((int)(b)); ++i)
- #define forit(it, v) for (typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
- #define forn(i, n) for (int i = 0; i < ((int)(n)); ++i)
- #define forabok(i, a, b, ok) for (int i = (int)(a); i < ((int)(b)) && (ok); ++i)
- #define foritok(it, v, ok) for (typeof((v).begin()) it = (v).begin(); it != (v).end() && (ok); ++it)
- #define fornok(i, n, ok) for (int i = 0; i < ((int)(n)) && (ok); ++i)
- #define mp make_pair
- #define pb push_back
- #define sz(a) ((int)((a).size()))
- #define X first
- #define Y second
- #define ibits(x) __builtin_popcount(x)
- #define lbits(x) __builtin_popcountll(x)
- typedef long long ll;
- typedef unsigned long long ull;
- typedef long double ld;
- typedef pair<int, int> ii;
- #if ( _WIN32 || __WIN32__ )
- #define LLD "%I64d"
- #else
- #define LLD "%lld"
- #endif
- /*-----------TEMPLATE---------------*/
- const int maxlen = (int)1e7 + 1000;
- const int maxn = (int)5e6;
- char s[maxlen];
- int slen, uniform[maxn];
- map<int, int> all_values;
- inline int get(int x) {
- if (all_values.count(x))
- return all_values[x];
- return all_values[x] = sz(all_values);
- }
- int position[maxlen], present[maxlen], total_counter;
- struct tree {
- int size, l, r, cnt;
- bool is_rev;
- tree *left, *right;
- int *numbers;
- int counter;
- char operation;
- tree(){}
- tree(int _l, int _r, int _size) : size(_size), l(_l), r(_r), is_rev(false) {
- left = 0;
- right = 0;
- numbers = 0;
- operation = 'n';
- }
- tree(tree * _left, tree * _right, char _operation) {
- left = _left;
- right = _right;
- operation = _operation;
- is_rev = false;
- l = left->l;
- r = right->r;
- size = left->size + right->size;
- if (left->size < right->size) {
- swap(left, right);
- }
- }
- void build_positions() {
- for(int i = 0; i < size; i++) {
- position[numbers[i]] = i;
- present[numbers[i]] = counter;
- }
- }
- void eval(int *from) {
- numbers = from;
- if (left == 0 && right == 0) {
- counter = ++total_counter;
- int pos = l;
- for(int i = 0; i < size; i++) {
- pos++;
- int x = 0;
- while(isdigit(s[pos])) {
- x = x*10 + s[pos] - '0';
- pos++;
- }
- numbers[i] = get(x);
- }
- build_positions();
- } else {
- counter = ++total_counter;
- int *source = right->numbers;
- int *destin = left->numbers;
- if (!(right->is_rev)) {
- for(int i = 0; i < right->size; i++) {
- if (left->is_rev ^ (present[source[i]] != left->counter)) {
- swap(source[i--], source[--right->size]);
- }
- }
- numbers = source;
- size = right->size;
- build_positions();
- } else {
- if (!left->is_rev && right->is_rev) {
- for(int i = 0; i < right->size; i++) {
- if (present[source[i]] == left->counter) {
- int v = position[source[i]];
- present[source[i]] = -1;
- position[destin[--left->size]] = v;
- swap(destin[v], destin[left->size]);
- }
- }
- } else {
- is_rev ^= true;
- for(int i = 0; i < right->size; i++) {
- int val = source[i];
- if (present[val] != left->counter) {
- present[val] = left->counter;
- position[val] = left->size;
- destin[left->size++] = val;
- }
- }
- }
- numbers = destin;
- size = left->size;
- counter = left->counter;
- }
- }
- }
- };
- char stack[maxlen];
- tree * tree_stack[maxlen];
- int stack_size, last, nums, l[maxlen];
- inline void build_and() {
- stack_size -= 2;
- tree_stack[stack_size - 1] = new tree(tree_stack[stack_size - 1], tree_stack[stack_size + 1], '&');
- }
- inline void build_or() {
- stack_size -= 2;
- tree_stack[stack_size - 1]->is_rev ^= true;
- tree_stack[stack_size + 1]->is_rev ^= true;
- tree_stack[stack_size - 1] = new tree(tree_stack[stack_size - 1], tree_stack[stack_size + 1], '&');
- tree_stack[stack_size - 1]->is_rev ^= true;
- }
- inline void build_not() {
- stack_size--;
- stack[stack_size - 1] = 'o';
- tree_stack[stack_size - 1] = tree_stack[stack_size];
- tree_stack[stack_size - 1]->is_rev ^= true;
- }
- inline void build_not_and() {
- while (stack_size > 1 && stack[stack_size - 2] == '!') {
- build_not();
- }
- while (stack_size > 1 && stack[stack_size - 2] == '&') {
- build_and();
- }
- }
- char simples[5] = "|&(!";
- bool is_ok;
- tree* build_tree() {
- for(last = 0; last < slen; last++) {
- if (count(simples, simples + 4, s[last]) == 1) {
- stack[stack_size++] = s[last];
- continue;
- }
- switch (s[last]) {
- case ',': {
- nums++;
- break;
- }
- case '{': {
- is_ok = true;
- nums = 1;
- stack[stack_size] = '{';
- l[stack_size] = last;
- stack_size++;
- break;
- }
- case '}': {
- if (s[last - 1] == '{') {
- nums = 0;
- }
- stack[stack_size - 1] = 'o';
- tree_stack[stack_size - 1] = new tree(l[stack_size - 1], last, nums);
- build_not_and();
- break;
- }
- case ')': {
- build_not_and();
- while (stack_size > 1 && stack[stack_size - 2] == '|') {
- build_or();
- }
- stack_size--;
- stack[stack_size - 1] = 'o';
- tree_stack[stack_size - 1] = tree_stack[stack_size];
- if (stack_size == 1) {
- return tree_stack[stack_size - 1];
- }
- build_not_and();
- break;
- }
- }
- }
- }
- void dfs(tree* num, int* tmp) {
- if (num->left == 0) {
- num->eval(tmp);
- return;
- }
- dfs(num->right, tmp + num->left->size);
- dfs(num->left, tmp);
- num->eval(tmp);
- }
- int calc() {
- slen = strlen(s);
- s[slen++] = ')';
- s[slen] = 0;
- all_values.clear();
- stack_size = 0;
- is_ok = false;
- tree *t = build_tree();
- if (is_ok) {
- dfs(t, uniform);
- return t->is_rev ? (1000000000 - t->size) : t->size;
- }
- return 0;
- }
- int main()
- {
- srand(time(NULL));
- #define TASK ""
- #ifdef HOME
- assert(freopen(TASK "in", "rt", stdin));
- assert(freopen(TASK "out", "wt", stdout));
- #endif
- int test = 0;
- s[0] = '(';
- while (gets(s + sizeof(char))) {
- printf("Case %d: %d\n", ++test, calc());
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement