Advertisement
Guest User

Untitled

a guest
Feb 10th, 2013
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.94 KB | None | 0 0
  1. /*-----------TEMPLATE---------------*/
  2. #include <algorithm>
  3. #include <cassert>
  4. #include <cctype>
  5. #include <cmath>
  6. #include <cstdarg>
  7. #include <cstdlib>
  8. #include <cstdio>
  9. #include <cstring>
  10. #include <ctime>
  11. #include <functional>
  12. #include <iterator>
  13. #include <map>
  14. #include <numeric>
  15. #include <set>
  16. #include <string>
  17. #include <vector>
  18.  
  19. using namespace std;
  20.  
  21. #define all(x) (x).begin(),(x).end()
  22. #define eprintf(...) {fprintf(stderr, __VA_ARGS__); fflush(stderr);}
  23. #define forab(i, a, b) for (int i = (int)(a); i < ((int)(b)); ++i)
  24. #define forit(it, v) for (typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
  25. #define forn(i, n) for (int i = 0; i < ((int)(n)); ++i)
  26. #define forabok(i, a, b, ok) for (int i = (int)(a); i < ((int)(b)) && (ok); ++i)
  27. #define foritok(it, v, ok) for (typeof((v).begin()) it = (v).begin(); it != (v).end() && (ok); ++it)
  28. #define fornok(i, n, ok) for (int i = 0; i < ((int)(n)) && (ok); ++i)
  29. #define mp make_pair
  30. #define pb push_back
  31. #define sz(a) ((int)((a).size()))
  32. #define X first
  33. #define Y second
  34. #define ibits(x) __builtin_popcount(x)
  35. #define lbits(x) __builtin_popcountll(x)
  36.  
  37. typedef long long ll;
  38. typedef unsigned long long ull;
  39. typedef long double ld;
  40. typedef pair<int, int> ii;
  41.  
  42. #if ( _WIN32 || __WIN32__ )
  43.     #define LLD "%I64d"
  44. #else
  45.     #define LLD "%lld"
  46. #endif
  47.  
  48. /*-----------TEMPLATE---------------*/
  49.  
  50. const int maxlen = (int)1e7 + 1000;
  51. const int maxn = (int)5e6;
  52.  
  53. char s[maxlen];
  54. int slen, uniform[maxn];
  55.  
  56. map<int, int> all_values;
  57.  
  58. inline int get(int x) {
  59.   if (all_values.count(x))
  60.     return all_values[x];
  61.   return all_values[x] = sz(all_values);
  62. }
  63.  
  64. int position[maxlen], present[maxlen], total_counter;
  65.  
  66. struct tree {
  67.   int size, l, r, cnt;
  68.   bool is_rev;
  69.   tree *left, *right;
  70.   int *numbers;
  71.   int counter;
  72.   char operation;
  73.  
  74.   tree(){}
  75.  
  76.   tree(int _l, int _r, int _size) : size(_size), l(_l), r(_r), is_rev(false) {
  77.     left = 0;
  78.     right = 0;
  79.     numbers = 0;
  80.     operation = 'n';
  81.   }
  82.  
  83.   tree(tree * _left, tree * _right, char _operation) {
  84.     left = _left;
  85.     right = _right;
  86.     operation = _operation;
  87.     is_rev = false;
  88.  
  89.     l = left->l;
  90.     r = right->r;
  91.     size = left->size + right->size;
  92.  
  93.     if (left->size < right->size) {
  94.       swap(left, right);
  95.     }
  96.   }
  97.  
  98.   void build_positions() {
  99.     for(int i = 0; i < size; i++) {
  100.         position[numbers[i]] = i;
  101.         present[numbers[i]]  = counter;
  102.     }
  103.   }
  104.  
  105.   void eval(int *from) {
  106.     numbers = from;
  107.     if (left == 0 && right == 0) {
  108.       counter = ++total_counter;
  109.       int pos = l;
  110.       for(int i = 0; i < size; i++) {
  111.         pos++;
  112.  
  113.         int x = 0;
  114.         while(isdigit(s[pos])) {
  115.           x = x*10 + s[pos] - '0';
  116.           pos++;
  117.         }
  118.         numbers[i] = get(x);
  119.       }
  120.       build_positions();
  121.     } else {
  122.       counter = ++total_counter;
  123.  
  124.       int *source = right->numbers;
  125.       int *destin = left->numbers;
  126.  
  127.       if (!(right->is_rev)) {
  128.         for(int i = 0; i < right->size; i++) {
  129.           if (left->is_rev ^ (present[source[i]] != left->counter)) {
  130.             swap(source[i--], source[--right->size]);
  131.           }
  132.         }
  133.         numbers = source;
  134.         size = right->size;
  135.         build_positions();
  136.  
  137.       } else {
  138.         if (!left->is_rev && right->is_rev) {
  139.           for(int i = 0; i < right->size; i++) {
  140.             if (present[source[i]] == left->counter) {
  141.               int v = position[source[i]];
  142.               present[source[i]] = -1;
  143.               position[destin[--left->size]] = v;
  144.               swap(destin[v], destin[left->size]);
  145.             }
  146.           }
  147.  
  148.         } else {
  149.           is_rev ^= true;
  150.           for(int i = 0; i < right->size; i++) {
  151.             int val = source[i];
  152.             if (present[val] != left->counter) {
  153.               present[val]  = left->counter;
  154.               position[val] = left->size;
  155.               destin[left->size++] = val;
  156.             }
  157.           }
  158.         }
  159.         numbers = destin;
  160.         size = left->size;
  161.         counter = left->counter;
  162.       }
  163.     }
  164.   }
  165. };
  166.  
  167. char stack[maxlen];
  168. tree * tree_stack[maxlen];
  169.  
  170. int stack_size, last, nums, l[maxlen];
  171.  
  172. inline void build_and() {
  173.   stack_size -= 2;
  174.   tree_stack[stack_size - 1] = new tree(tree_stack[stack_size - 1], tree_stack[stack_size + 1], '&');
  175. }
  176.  
  177. inline void build_or() {
  178.   stack_size -= 2;
  179.   tree_stack[stack_size - 1]->is_rev ^= true;
  180.   tree_stack[stack_size + 1]->is_rev ^= true;
  181.   tree_stack[stack_size - 1] = new tree(tree_stack[stack_size - 1], tree_stack[stack_size + 1], '&');
  182.   tree_stack[stack_size - 1]->is_rev ^= true;
  183. }
  184.  
  185. inline void build_not() {
  186.   stack_size--;
  187.   stack[stack_size - 1] = 'o';
  188.   tree_stack[stack_size - 1] = tree_stack[stack_size];
  189.   tree_stack[stack_size - 1]->is_rev ^= true;
  190. }
  191.  
  192. inline void build_not_and() {
  193.   while (stack_size > 1 && stack[stack_size - 2] == '!') {
  194.     build_not();
  195.   }
  196.   while (stack_size > 1 && stack[stack_size - 2] == '&') {
  197.     build_and();
  198.   }
  199. }
  200.  
  201. char simples[5] = "|&(!";
  202. bool is_ok;
  203. tree* build_tree() {
  204.   for(last = 0; last < slen; last++) {
  205.     if (count(simples, simples + 4, s[last]) == 1) {
  206.       stack[stack_size++] = s[last];
  207.       continue;
  208.     }
  209.     switch (s[last]) {
  210.       case ',': {
  211.         nums++;
  212.         break;
  213.       }
  214.       case '{': {
  215.         is_ok = true;
  216.         nums = 1;
  217.         stack[stack_size] = '{';
  218.         l[stack_size] = last;
  219.         stack_size++;
  220.         break;
  221.       }
  222.       case '}': {
  223.         if (s[last - 1] == '{') {
  224.           nums = 0;
  225.         }
  226.         stack[stack_size - 1] = 'o';
  227.         tree_stack[stack_size - 1] = new tree(l[stack_size - 1], last, nums);
  228.         build_not_and();
  229.         break;
  230.       }
  231.       case ')': {
  232.         build_not_and();
  233.         while (stack_size > 1 && stack[stack_size - 2] == '|') {
  234.           build_or();
  235.         }
  236.  
  237.         stack_size--;
  238.         stack[stack_size - 1] = 'o';
  239.         tree_stack[stack_size - 1] = tree_stack[stack_size];
  240.  
  241.         if (stack_size == 1) {
  242.           return tree_stack[stack_size - 1];
  243.         }
  244.  
  245.         build_not_and();
  246.         break;
  247.       }
  248.     }                                                                                  
  249.   }
  250. }
  251.  
  252. void dfs(tree* num, int* tmp) {
  253.   if (num->left == 0) {
  254.     num->eval(tmp);
  255.     return;
  256.   }
  257.   dfs(num->right, tmp + num->left->size);
  258.   dfs(num->left, tmp);
  259.   num->eval(tmp);
  260. }
  261.  
  262.  
  263. int calc() {
  264.   slen = strlen(s);
  265.   s[slen++] = ')';
  266.   s[slen] = 0;
  267.   all_values.clear();
  268.  
  269.   stack_size = 0;
  270.   is_ok = false;
  271.   tree *t = build_tree();
  272.  
  273.   if (is_ok) {
  274.     dfs(t, uniform);
  275.     return t->is_rev ? (1000000000 - t->size) : t->size;
  276.   }
  277.   return 0;
  278. }
  279. int main()
  280. {
  281.   srand(time(NULL));
  282.   #define TASK ""
  283.   #ifdef HOME
  284.   assert(freopen(TASK "in", "rt", stdin));
  285.   assert(freopen(TASK "out", "wt", stdout));
  286.   #endif
  287.  
  288.   int test = 0;
  289.   s[0] = '(';
  290.   while (gets(s + sizeof(char))) {
  291.     printf("Case %d: %d\n", ++test, calc());
  292.   }
  293.   return 0;
  294. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement