Mrowqa

Ile inwersji II (nietestowane)

Aug 8th, 2014
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.26 KB | None | 0 0
  1. #include <cstdio>
  2. #include <algorithm>
  3.  
  4. const int MAXN = 5e5; // REMEMBER!!! change S below too!
  5. char buff[MAXN+1];
  6.  
  7. typedef long long LL;
  8. struct Node {
  9.     int a, b;
  10.     LL inv, rev_inv;
  11.     bool is_reversed;
  12.  
  13.     Node() : a(0), b(0), inv(0), rev_inv(0), is_reversed(false) {}
  14.  
  15.     Node operator+(const Node& o) const {
  16.         Node res;
  17.         res.a = a + o.a;
  18.         res.b = b + o.b;
  19.         res.inv = inv + b * o.a + o.inv;
  20.         res.rev_inv = rev_inv + a * o.b + o.rev_inv;
  21.         return res;
  22.     }
  23.  
  24.     Node& reverse_me() {
  25.         std::swap(inv, rev_inv);
  26.         std::swap(a, b);
  27.         is_reversed = !is_reversed;
  28.         return *this;
  29.     }
  30. };
  31.  
  32. const int S = 1<<19; // FOR MAXN=5e5 !!!!
  33. struct Tree {
  34.     Node v[2*S];
  35.  
  36.     Node query(int a, int b, bool reverse = false, int left = 0, int right = S-1, int me_ind = 1) {
  37.         if(a<=left && b>=right) {
  38.             if(reverse)
  39.                 v[me_ind].reverse_me();
  40.             return v[me_ind];
  41.         }
  42.  
  43.         // zepchnij aktualizacje na synow
  44.         if(v[me_ind].is_reversed && me_ind < S) { // hm, drugi warunek zawsze prawdziwy...
  45.             v[me_ind*2].reverse_me();
  46.             v[me_ind*2+1].reverse_me();
  47.         }
  48.  
  49.  
  50.         Node left_son, right_son;
  51.         // lewy syn
  52.         if(a <= (left+right)/2)
  53.             left_son = query(a, b, reverse, left, (left+right)/2, me_ind*2);
  54.         // prawy syn
  55.         if(b >= (left+right)/2+1)
  56.             right_son = query(a, b, reverse, (left+right)/2+1, right, me_ind*2+1);
  57.  
  58.         v[me_ind] = v[me_ind*2] + v[me_ind*2+1];
  59.  
  60.         return left_son + right_son;
  61.     }
  62.  
  63.  
  64.     // helper init function !
  65.     void build_tree(const char* buff) {
  66.         for(int i=0; buff[i]; i++)
  67.             if(buff[i]=='a')
  68.                 v[S+i+1].a++;
  69.             else
  70.                 v[S+i+1].b++;
  71.  
  72.         int ind = S;
  73.         while(--ind)
  74.             v[ind] = v[ind*2] + v[ind*2+1];
  75.     }
  76. };
  77.  
  78.  
  79. Tree t;
  80. int main()
  81. {
  82.     int q,n;
  83.     scanf("%i %i %s", &q, &n, buff);
  84.     t.build_tree(buff);
  85.  
  86.     while(q--) {
  87.         char c; int a,b;
  88.         scanf("%c%c %i %i", &c, &c, &a, &b);
  89.  
  90.         if(c=='I')
  91.             t.query(a,b,true);
  92.         else
  93.             printf("%lld\n", t.query(a,b).inv);
  94.     }
  95.  
  96.     return 0;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment