4eyes4u

Persistent segment tree

Feb 17th, 2017
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.36 KB | None | 0 0
  1. /*
  2. Persistent segment tree
  3.  
  4. Query complexity: O(logN)
  5. Update complexity: O(logN)
  6. Additional memory: O(NlogN)
  7.  
  8. Test: http://www.spoj.com/problems/MKTHNUM/
  9. */
  10.  
  11. #include <bits/stdc++.h>
  12. #define mid (left+right)/2
  13. using namespace std;
  14.  
  15. const int N=1e5+10;
  16. const int LogN=20;
  17.  
  18. struct Node
  19. {
  20.     int val;
  21.     Node *l, *r;
  22. };
  23.  
  24. vector<Node *> roots;
  25. vector<pair<int, int> > v;
  26. map<int, int> hmp;
  27. int n, q, k;
  28. int a[N];
  29.  
  30. void compress (vector<pair<int, int> > &v, int &k, int *a)
  31. {
  32.     sort (v.begin(), v.end());
  33.     int last=-2e9;
  34.     for (auto xt: v)
  35.     {
  36.         if (xt.first!=last) k++;
  37.         a[xt.second]=k;
  38.         hmp[k]=xt.first;
  39.         last=xt.first;
  40.     }
  41. }
  42.  
  43. void init (Node *v, int left, int right)
  44. {
  45.     if (left==right) return;
  46.     v->l=new Node();
  47.     v->r=new Node();
  48.     init (v->l, left, mid);
  49.     init (v->r, mid+1, right);
  50. }
  51.  
  52. void update (Node *v, Node *u, int left, int right, int x)
  53. {
  54.     v->val=u->val+1;
  55.     if (left==right) return;
  56.  
  57.     if (x<=mid)
  58.     {
  59.         v->l=new Node();
  60.         v->r=u->r;
  61.         update (v->l, u->l, left, mid, x);
  62.     }
  63.     else
  64.     {
  65.         v->r=new Node();
  66.         v->l=u->l;
  67.         update (v->r, u->r, mid+1, right, x);
  68.     }
  69. }
  70.  
  71. int query (Node *v, int left, int right, int l, int r)
  72. {
  73.     if (l<=left && right<=r) return v->val;
  74.  
  75.     int ret=0;
  76.     if (l<=mid) ret+=query(v->l, left, mid, l, r);
  77.     if (r>mid) ret+=query(v->r, mid+1, right, l, r);
  78.     return ret;
  79. }
  80.  
  81. int main()
  82. {
  83.     scanf ("%d%d", &n, &q);
  84.     for (int i=1;i<=n;i++)
  85.     {
  86.         scanf ("%d", &a[i]);
  87.         v.push_back({a[i], i});
  88.     }
  89.  
  90.     compress(v, k, a);
  91.  
  92.     roots.push_back(new Node());
  93.     init (roots[0], 1, n);
  94.     for (int i=1;i<=n;i++)
  95.     {
  96.         roots.push_back(new Node());
  97.         update (roots.back(), roots[(int)roots.size()-2], 1, n, a[i]);
  98.     }
  99.  
  100.     while (q--)
  101.     {
  102.         int l, r, m;
  103.         scanf ("%d%d%d", &l, &r, &m);
  104.  
  105.         int low=1, up=k, half, ret;
  106.         while (low<=up)
  107.         {
  108.             half=(low+up)/2;
  109.             int lpart=query(roots[l-1], 1, n, 1, half);
  110.             int rpart=query(roots[r], 1, n, 1, half);
  111.             if (rpart-lpart<m) low=half+1;
  112.             else
  113.             {
  114.                 up=half-1;
  115.                 ret=half;
  116.             }
  117.         }
  118.  
  119.         printf ("%d\n", hmp[ret]);
  120.     }
  121.  
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment