Advertisement
istinishat

Implicit Treap

Jul 16th, 2017
364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define si(n) scanf("%d",&n)
  5. #define f first
  6. #define s second
  7. #define mp(a,b) make_pair(a,b)
  8. #define INF 1e9
  9. #define ll long long
  10.  
  11. /*
  12. One possible solution would be to create some binary tree representing the array.
  13. And that is where implicite key comes into play.
  14. Array index will be our implicite key, that is we consider one element greater if it has greater array index.
  15. In our tree that means, if we take k smallest elements, we will get elements with indices [0..k−1]
  16. */
  17.  
  18. /*
  19. features :
  20.     1.insert an array item in log(n)
  21.     2.delete an array item/segment in log(n)
  22.     3.split array from 1...x and x+1...n in log(n)
  23.     4.join two segment in log(n)
  24.     5.find min in log(n)
  25.  
  26. */
  27.  
  28. //Implicit Treap
  29. struct Treap{
  30.     int x,y;// x is the key value(value stored in array), y is priority (random value)
  31.     Treap * left;
  32.     Treap * right;
  33.     int min_;//min value of the entire tree
  34.     int sz;//size of the entire tree
  35.     Treap(int x,int y) : x(x),y(y),left(NULL),right(NULL),min_(x),sz(1) {}
  36.  
  37. };
  38.  
  39. typedef Treap * treap;
  40.  
  41. //find minimum value starting from pointer a
  42. int safe_min(treap a){
  43.     if(!a)return INF;
  44.     return a -> min_;
  45. }
  46.  
  47. //find size under the subtree from pointer a
  48. int safe_sz(treap a){
  49.     if(!a)return 0;
  50.     return a->sz;
  51. }
  52.  
  53. // recalculate size and min value
  54. void recalc(treap a){
  55.     a->min_=min(a->x,min(safe_min(a->left),safe_min(a->right)));
  56.     a->sz=1+safe_sz(a->left)+safe_sz(a->right);
  57. }
  58.  
  59. //merge treap a and b
  60. treap Merge(treap a,treap b){
  61.     if(!a)return b;
  62.     if(!b)return a;
  63.     if(a->y > b->y){
  64.         a->right=Merge(a->right,b);
  65.         recalc(a);
  66.         return a;
  67.     }
  68.     else{
  69.         b->left=Merge(a,b->left);
  70.         recalc(b);
  71.         return b;
  72.     }
  73. }
  74.  
  75.  
  76. //return two Treap L,R. L is from first to array index x
  77. //and R is the rest.Here array index is used to split
  78. //hence named Implicit Treap
  79. pair<treap,treap> split_size(treap a,int x){
  80.     if(!a)return mp((treap)NULL,(treap)NULL);
  81.     int sz=safe_sz(a->left)+1;
  82.     if(sz<=x){
  83.         auto u=split_size(a->right,x-sz);
  84.         a->right=u.f;
  85.         recalc(a);
  86.         return mp(a,u.s);
  87.     }
  88.     else{
  89.         auto u=split_size(a->left,x);
  90.         a->left=u.s;
  91.         recalc(a);
  92.         return mp(u.f,a);
  93.     }
  94. }
  95.  
  96. //find position of the min element in the treap(1-based)
  97. int find_pos_of_min(treap a){
  98.     if(safe_min(a->left) != a->min_){
  99.         if(a->x != a->min_){
  100.             return find_pos_of_min(a->right)+safe_sz(a->left)+1;
  101.         }
  102.         else{
  103.             return 1+safe_sz(a->left);
  104.         }
  105.     }
  106.     else{
  107.         return find_pos_of_min(a->left);
  108.     }
  109. }
  110.  
  111.  
  112. int main()
  113. {
  114.     srand(12345);
  115.     int i,j,p,n;
  116.     si(n);
  117.     treap root=NULL;
  118.     for(i=0;i<n;i++){
  119.         si(p);
  120.         root=Merge(root,new Treap(p,rand()));
  121.     }
  122.     ll ans=0;
  123.     while(root){
  124.         int v=find_pos_of_min(root);
  125.         auto u=split_size(root,v-1);//splitting treap from index 1 to v-1 and v to size.
  126.         ans+=safe_sz(u.f)+1;
  127.         auto r=split_size(u.s,1);//splitting two parts.left part consists 1 element and right part consists rest
  128.         root=Merge(r.s,u.f);
  129.     }
  130.     printf("%I64d\n",ans);
  131.  
  132.     return 0;
  133. }
  134. problem Link: http://codeforces.com/contest/831/problem/E
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement