Advertisement
radoslav11

Implicit treap

May 31st, 2016
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.19 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define endl '\n'
  3.  
  4. using namespace std;
  5. const int MAXN = (1 << 20);
  6.  
  7. struct implicit_treap
  8. {
  9.     struct node
  10.     {
  11.         int val, sz, priority, lazy, rev, sum;
  12.         node *l, *r, *par;
  13.  
  14.         node() { lazy = 0; rev = 0; val = 0; sz = 0; priority = 0; l = NULL; r = NULL; par = NULL;}
  15.         node(int _val)
  16.         {
  17.             val = _val;
  18.             sum = _val;
  19.             rev = 0;
  20.             lazy = 0;
  21.             sz = 1;
  22.             priority = rand();
  23.  
  24.             l = NULL;
  25.             r = NULL;
  26.             par = NULL;
  27.         }
  28.     };
  29.  
  30.     typedef node* pnode;
  31.  
  32.     pnode root;
  33.     map<int, pnode> position;
  34.    
  35.     void clear()
  36.     {
  37.         root = NULL;
  38.         position.clear();
  39.     }
  40.  
  41.     implicit_treap() { clear(); }
  42.  
  43.     int size(pnode p) { return p ? p->sz : 0; }
  44.     void update_size(pnode &p) { if(p) p->sz = size(p->l) + size(p->r) + 1; }
  45.    
  46.     void update_parent(pnode &p)
  47.     {
  48.         if(!p) return;
  49.         if(p->l) p->l->par = p;
  50.         if(p->r) p->r->par = p;
  51.     }
  52.  
  53.     void lazy(pnode &p)
  54.     {
  55.         if(!p) return;     
  56.         p->sum += size(p) * p->lazy;
  57.         p->val += p->lazy;
  58.  
  59.         if(p->rev) swap(p->l, p->r);
  60.        
  61.         if(p->l) { p->l->lazy += p->lazy; p->l->rev ^= p->rev; }
  62.         if(p->r) { p->r->lazy += p->lazy; p->r->rev ^= p->rev; }
  63.    
  64.         p->lazy = 0;
  65.         p->rev = 0;
  66.     }
  67.  
  68.     void reset(pnode &t) { if(t) t->sum = t->val; }
  69.  
  70.     void combine(pnode &t, pnode l, pnode r)
  71.     {
  72.         if(!l) { t = r; return; }
  73.         if(!r) { t = l; return; }
  74.         t->sum = l->sum + r->sum;
  75.     }
  76.  
  77.     void operation(pnode &t)
  78.     {
  79.         if(!t) return;
  80.  
  81.         reset(t);
  82.         lazy(t->l);
  83.         lazy(t->r);
  84.  
  85.         combine(t, t->l, t);
  86.         combine(t, t, t->r);
  87.     }
  88.  
  89.     void split(pnode t, pnode &l, pnode &r, int k, int add = 0)
  90.     {
  91.         if(t == NULL) { l = NULL; r = NULL; return; }
  92.         lazy(t);
  93.  
  94.         int idx = add + size(t->l);
  95.         if(idx <= k)
  96.             split(t->r, t->r, r, k, idx + 1), l = t;
  97.         else
  98.             split(t->l, l, t->l, k, add), r = t;
  99.  
  100.         update_parent(t);
  101.         update_size(t);
  102.         operation(t);
  103.     }
  104.  
  105.     void merge(pnode &t, pnode l, pnode r)
  106.     {
  107.         lazy(l);
  108.         lazy(r);
  109.  
  110.         if(!l) { t = r; return; }
  111.         if(!r) { t = l; return; }
  112.  
  113.         if(l->priority > r->priority)
  114.             merge(l->r, l->r, r), t = l;
  115.         else
  116.             merge(r->l, l, r->l), t = r;
  117.  
  118.         update_parent(t);
  119.         update_size(t);
  120.         operation(t);
  121.     }
  122.  
  123.     void insert(int pos, int val)
  124.     {
  125.         if(root == NULL)
  126.         {
  127.             pnode to_add = new node(val);
  128.             root = to_add;
  129.             position[val] = root;
  130.             return;
  131.         }
  132.  
  133.         pnode l, r, mid;
  134.         mid = new node(val);
  135.         position[val] = mid;
  136.  
  137.         split(root, l, r, pos - 1);
  138.         merge(l, l, mid);
  139.         merge(root, l, r);
  140.     }
  141.  
  142.     void erase(int qL, int qR)
  143.     {
  144.         pnode l, r, mid;
  145.        
  146.         split(root, l, r, qL - 1);
  147.         split(r, mid, r, qR - qL);
  148.         merge(root, l, r);
  149.     }
  150.  
  151.     int query(int qL, int qR)
  152.     {
  153.         pnode l, r, mid;
  154.  
  155.         split(root, l, r, qL - 1);
  156.         split(r, mid, r, qR - qL);
  157.  
  158.         int answer = mid->sum;
  159.    
  160.         merge(r, mid, r);
  161.         merge(root, l, r);
  162.  
  163.         return answer;
  164.     }
  165.  
  166.     void update(int qL, int qR, int val)
  167.     {
  168.         pnode l, r, mid;
  169.  
  170.         split(root, l, r, qL - 1);
  171.         split(r, mid, r, qR - qL);
  172.  
  173.         mid->lazy += val;
  174.  
  175.         merge(r, mid, r);
  176.         merge(root, l, r);
  177.     }
  178.  
  179.     void reverse(int qL, int qR)
  180.     {
  181.         pnode l, r, mid;
  182.  
  183.         split(root, l, r, qL - 1);
  184.         split(r, mid, r, qR - qL);
  185.  
  186.         mid->rev ^= 1;
  187.         merge(r, mid, r);
  188.         merge(root, l, r);
  189.     }
  190.  
  191.     void cyclic_shift(int qL, int qR, int k)
  192.     {
  193.         if(qL == qR) return;
  194.         k %= (qR - qL + 1);
  195.  
  196.         pnode l, r, mid, fh, sh;
  197.         split(root, l, r, qL - 1);
  198.         split(r, mid, r, qR - qL);
  199.  
  200.         split(mid, fh, sh, (qR - qL + 1) - k - 1);
  201.         merge(mid, sh, fh);
  202.  
  203.         merge(r, mid, r);
  204.         merge(root, l, r);
  205.     }
  206.  
  207.     int get_pos(pnode curr, pnode son = nullptr)
  208.     {
  209.         if(!son)
  210.             if(curr == root) return size(curr->l);
  211.             else return size(curr->l) + get_pos(curr->par, curr);
  212.  
  213.         if(curr == root)
  214.             if(son == curr->l) return 0;
  215.             else return size(curr->l) + 1;
  216.  
  217.         if(curr->l == son) return get_pos(curr->par, curr);
  218.         else return get_pos(curr->par, curr) + size(curr->l) + 1;
  219.     }
  220.  
  221.     int get_pos(int value) { return get_pos(position[value]); }
  222. };
  223.  
  224. int n;
  225. int a[MAXN];
  226.  
  227. void read()
  228. {
  229.     cin >> n;
  230.     for(int i = 0; i < n; i++)
  231.         cin >> a[i];
  232. }
  233.  
  234. implicit_treap t;
  235.  
  236. void solve()
  237. {
  238.     t.clear();
  239.     for(int i = 0; i < n; i++)
  240.         t.insert(i, a[i]);
  241.  
  242. }
  243.  
  244. int main()
  245. {
  246.     ios_base::sync_with_stdio(false);
  247.     cin.tie(NULL);
  248.  
  249.     read();
  250.     solve();
  251.     return 0;
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement