码迷,mamicode.com
首页 > 其他好文 > 详细

Splay 夏大神版

时间:2015-09-05 14:59:28      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

  1 struct Splay{
  2     struct obj{
  3         int s,v,cnt;
  4         obj*f,*c[2];
  5         obj(int _v=0,int _cnt=0,obj*_f=null):
  6             v(_v),cnt(_cnt),f(_f){c[0]=c[1]=null;}
  7         void gets(){
  8             s=size(c[0])+cnt+size(c[1]);
  9         }
 10     }*root;
 11  
 12     void rotate(obj*x){
 13         obj*y=x->f;
 14         if(y==null)return;
 15         int d=x==y->c[0];
 16         y->c[!d]=x->c[d];
 17         if(x->c[d])x->c[d]->f=y;
 18         x->f=y->f;
 19         if(y->f)y->f->c[y==y->f->c[1]]=x;
 20         y->f=x,x->c[d]=y;
 21         y->gets(),x->gets();
 22         if(y==root)root=x;
 23     }
 24  
 25     void splay(obj*x,obj*f){
 26         while(x->f!=f){
 27             if(x->f->f==f) rotate(x);
 28             else rotate(((x->f->f->v>x->f->v)^(x->f->v>x->v))?x:x->f),rotate(x);
 29         }
 30         x->gets();
 31     }
 32  
 33     void insert(int v){
 34         if(root==null){
 35             root=new obj(v,1,null);
 36             return;
 37         }
 38         obj*x=root,*y=null;
 39         while(x&&x->v!=v)y=x,x=x->c[v>x->v];
 40         if(x){
 41             x->cnt++;
 42             splay(x,null);
 43         }else{
 44             x=new obj(v,1,y);
 45             if(y)y->c[v>y->v]=x;
 46             splay(x,null);
 47         }
 48     }
 49  
 50     void del(int v){
 51         obj*x=root;
 52         while(x&&x->v!=v)x=x->c[v>x->v];
 53         if(x==null)return;
 54         else if(x->cnt>1){
 55             x->cnt--;
 56             splay(x,null);
 57             return;
 58         }
 59         splay(x,null);
 60         if(x->c[0]){
 61             x=x->c[0];
 62             while(x->c[1])x=x->c[1];
 63             splay(x,root);
 64             x->f=null,x->c[1]=root->c[1];
 65             if(root->c[1])root->c[1]->f=x;
 66             swap(x,root);
 67             delete x;
 68         }else{
 69             x=x->c[1];
 70             if(x)x->f=null;
 71             swap(x,root);
 72             delete x;
 73         }
 74     }
 75  
 76     void display(obj*root){
 77         if(!root)return;
 78         display(root->c[0]);
 79         printf("%d ",root->v);
 80         display(root->c[1]);
 81     }
 82  
 83     obj*kth(int k){
 84         for(obj*x=root;x;){
 85             if(size(x->c[0])+1==k)return x;
 86             else if(size(x->c[0])>=k)x=x->c[0];
 87             else k-=size(x->c[0])+1,x=x->c[1];
 88         }
 89     }
 90  
 91     void clean(obj*x){
 92         if(x==null)return;
 93         clean(x->c[0]),clean(x->c[1]);
 94         delete x;
 95     }
 96  
 97     int next(int v){
 98         int ans=INF;
 99         for(obj*x=root;x;){
100             if(x->v>v)ans=min(ans,x->v),x=x->c[0];
101             else x=x->c[1];
102         }
103         return ans;
104     }
105  
106     int prev(int v){
107         int ans=-INF;
108         for(obj*x=root;x;){
109             if(x->v<v)ans=max(ans,x->v),x=x->c[1];
110             else x=x->c[0];
111         }
112         return ans;
113     }
114  
115     int knum(int v){
116         obj*x=root;
117         while(x&&x->v!=v)x=x->c[v>x->v];
118         if(x)return x->cnt;
119         else return 0;
120     }
121  
122     int rank(int v){
123         obj*x=root;
124         int ans=0;
125         while(x&&x->v!=v){
126             if(x->v<v) ans+=size(x->c[0])+x->cnt,x=x->c[1];
127             else x=x->c[0];
128         }
129         return ans+(x?size(x->c[0]):0);
130     }
131  
132     void init(){clean(root);root=null;}
133     Splay(){root=null;}
134     ~Splay(){clean(root);root=null;}
135 };
136  
137 int l[maxn],r[maxn],ls[maxn],rs[maxn],mid[maxn],lotree;
138 Splay data[maxn];
139 int build(int _l, int _r){
140     int root=lotree++;
141     l[root]=_l,r[root]=_r,mid[root]=(_l+_r)/2,data[root].init();
142     if(_l!=_r)ls[root]=build(_l,mid[root]),rs[root]=build(mid[root]+1,_r);
143     else ls[root]=-1,rs[root]=-1;
144     return root;
145 }
146  
147 int arr[maxn];
148 void add(int root,int pos, int _data){
149     if(root==-1)return;
150     data[root].insert(_data);
151     if (pos<=mid[root])add(ls[root],pos,_data);
152     else add(rs[root],pos,_data);
153 }
154  
155 void modify(int root,int pos,int _data){
156     if(root==-1)return;
157     data[root].del(arr[pos]);
158     data[root].insert(_data);
159     if (pos<=mid[root])modify(ls[root],pos,_data);
160     else modify(rs[root],pos,_data);
161 }
162  
163 int next(int root, int _l, int _r, int v){
164     _l=max(_l,l[root]),_r=min(_r,r[root]);
165     if(_l>_r)return INF;
166     if(_l==l[root]&&_r==r[root])return data[root].next(v);
167     else return min(next(ls[root],_l,_r,v),next(rs[root],_l,_r,v));
168 }
169  
170 int prev(int root, int _l, int _r, int v){
171     _l=max(_l,l[root]),_r=min(_r,r[root]);
172     if(_l>_r)return -INF;
173     if(_l==l[root]&&_r==r[root])return data[root].prev(v);
174     else return max(prev(ls[root],_l,_r,v),prev(rs[root],_l,_r,v));
175 }
176  
177 int rank(int root,int _l,int _r,int k){
178     _l=max(_l,l[root]),_r=min(_r,r[root]);
179     if(_l>_r)return 0;
180     if(_l==l[root]&&_r==r[root])return data[root].rank(k);
181     else return rank(ls[root],_l,_r,k)+rank(rs[root],_l,_r,k);
182 }
183  
184 int knum(int root,int _l,int _r,int k){
185     _l=max(_l,l[root]),_r=min(_r,r[root]);
186     if(_l>_r)return 0;
187     if(_l==l[root]&&_r==r[root])return data[root].knum(k);
188     else return knum(ls[root],_l,_r,k)+knum(rs[root],_l,_r,k);
189 }
190  
191 int kth(int root,int _l,int _r,int k){
192     int head=0,tail=100000001;
193     while(tail-head>1){
194         int mid=(head+tail)/2;
195         if (rank(root, _l,_r,mid)<k)head=mid;
196         else tail=mid;
197     }
198     return head;
199 }
200  
201 int main()
202 {
203     //FF;
204     int n,m;
205     while(~scanf("%d%d",&n,&m)){
206         lotree=0;
207         int root=build(1,n);
208         for(int i=1;i<=n;i++)scanf("%d",arr+i),add(root,i,arr[i]);
209         while(m--){
210             int o,t1,t2,t3;
211             scanf("%d",&o);
212             switch(o){
213             case 1:
214                 scanf("%d%d%d",&t1,&t2,&t3);
215                 printf("%d\n",rank(root,t1,t2,t3)+1);
216                 break;
217             case 2:
218                 scanf("%d%d%d",&t1,&t2,&t3);
219                 printf("%d\n",kth(root,t1,t2,t3));
220                 break;
221             case 3:
222                 scanf("%d%d",&t1,&t2);
223                 modify(root,t1,t2);
224                 arr[t1]=t2;
225                 break;
226             case 4:
227                 scanf("%d%d%d",&t1,&t2,&t3);
228                 printf("%d\n",prev(root,t1,t2,t3));
229                 break;
230             case 5:
231                 scanf("%d%d%d",&t1,&t2,&t3);
232                 printf("%d\n",next(root,t1,t2,t3));
233                 break;
234             }
235         }
236     }
237 }

 

Splay 夏大神版

标签:

原文地址:http://www.cnblogs.com/mitrenick/p/4783183.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!