TYVJ P1730 二逼平衡树

ttp://tyvj.cpwz.cn/Problem_Show.asp?id=1730

 

 

背景 Background  
  此为平衡树系列最后一道:二逼平衡树
     
     
  描述 Description  
  您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)
     
     
  输入格式 Input Format  
  第一行两个数 n,m 表示长度为n的有序序列和m个操作
第二行有n个数,表示有序序列
下面有m行,opt表示操作标号
若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继
     
     
  输出格式 Output Format  
  对于操作1,2,4,5各输出一行,表示查询结果
     
     
  样例输入 Sample Input [复制数据]  
 

9 6
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5


     
     
  样例输出 Sample Output [复制数据]  
 

2
4
3
4
9


     
     
  时间限制 Time Limitation  
  各个测试点2s
     
     
  注释 Hint  
  n,m<=50000   保证有序序列所有值在任何时刻满足[0,10^8]

题解:

  线段树套平衡树之神级恶心题………………………………考验人的代码能力的…………………………

 

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 
  5 using namespace std;
  6 
  7 const int INF=123456789;
  8 
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 
 12 const int maxn=50001;
 13 const int maxm=maxn*20;
 14 
 15 int min_num,max_num,lastv,z[maxn],n,m,sum;
 16 
 17 int min(int a,int b)
 18 {
 19     if (a<b) return a;
 20     else return b;
 21 }
 22 
 23 int max(int a,int b)
 24 {
 25     if (a>b) return a;
 26     else return b;
 27 }
 28 
 29 void swap(int &a,int &b)
 30 {
 31     int c=a;a=b;b=c;
 32 }
 33 
 34 struct node
 35 {
 36     int f,value,l,r,size;
 37     node()
 38     {
 39         f=value=l=r=size=0;
 40     }
 41 }point[maxm];
 42 
 43 struct splay_tree
 44 {
 45     node *z;
 46     int root,size;
 47     splay_tree()
 48     {
 49         root=size=0;
 50     }
 51     void build_z(int now)
 52     {
 53         z=point+now;
 54     }
 55     void update(int now)
 56     {
 57         z[now].size=z[z[now].l].size+z[z[now].r].size+1;
 58     }
 59     void rot_l(int now)
 60     {
 61         int a=z[now].r;
 62         z[now].r=z[a].l;
 63         z[a].l=now;
 64         update(now);
 65         update(a);
 66         if (now==root) root=a;
 67         else
 68         {
 69             if (z[z[now].f].l==now) z[z[now].f].l=a;
 70             else z[z[now].f].r=a;
 71         }
 72         z[a].f=z[now].f;
 73         z[now].f=a;
 74         z[z[now].r].f=now;
 75     }
 76     void rot_r(int now)
 77     {
 78         int a=z[now].l;
 79         z[now].l=z[a].r;
 80         z[a].r=now;
 81         update(now);
 82         update(a);
 83         if (root==now) root=a;
 84         else 
 85         {
 86             if (z[z[now].f].l==now) z[z[now].f].l=a;
 87             else z[z[now].f].r=a;
 88         }
 89         z[a].f=z[now].f;
 90         z[now].f=a;
 91         z[z[now].l].f=now;
 92     }
 93     void rot_l1(int now)
 94     {
 95         int a=z[now].r;
 96         z[now].r=z[a].l;
 97         z[a].l=now;
 98         update(now);
 99         if (now==root) root=a;
100         else
101         {
102             if (z[z[now].f].l==now) z[z[now].f].l=a;
103             else z[z[now].f].r=a;
104         }
105         z[a].f=z[now].f;
106         z[now].f=a;
107         z[z[now].r].f=now;
108     }
109     void rot_r1(int now)
110     {
111         int a=z[now].l;
112         z[now].l=z[a].r;
113         z[a].r=now;
114         update(now);
115         if (root==now) root=a;
116         else 
117         {
118             if (z[z[now].f].l==now) z[z[now].f].l=a;
119             else z[z[now].f].r=a;
120         }
121         z[a].f=z[now].f;
122         z[now].f=a;
123         z[z[now].l].f=now;
124     }
125     void splay(int now,int goal)
126     {
127         while (z[now].f!=goal)
128         {
129             int f=z[now].f;
130             int ff=z[f].f;
131             if (ff==goal)
132             {
133                 if (z[f].l==now) rot_r(f);
134                 else rot_l(f);
135             }
136             else
137             {
138                 if ((z[ff].l==f) && (z[f].l==now))
139                 {
140                     rot_r(ff);
141                     rot_r1(f);
142                 }
143                 if ((z[ff].r==f) && (z[f].r==now))
144                 {
145                     rot_l(ff);
146                     rot_l1(f);
147                 }
148                 if ((z[ff].l==f) && (z[f].r==now))
149                 {
150                     rot_l1(f);
151                     rot_r1(ff);
152                 }
153                 if ((z[ff].r==f) && (z[f].l==now))
154                 {
155                     rot_r1(f);
156                     rot_l1(ff);
157                 }
158             }
159         }
160         update(now);
161         if (goal==0) root=now;
162     }
163     void insert(int v,int orz)
164     {
165         if (!orz)
166         {
167             size++;
168             z[size].value=v;
169             z[size].size=1;
170             z[size].l=z[size].r=0;
171             orz=size;
172         }
173         else
174         {
175             size++;
176             z[orz].value=v;
177             z[orz].size=1;
178             z[orz].l=z[orz].r=0;
179             swap(orz,size);
180         }
181         if (root==0) root=size;
182         else
183         {
184             int pos=root,lastp;
185             while (pos)
186             {
187                 lastp=pos;
188                 z[pos].size++;
189                 if (v>z[pos].value) pos=z[pos].r;
190                 else pos=z[pos].l;
191             }
192             z[size].f=lastp;
193             if    (v>z[lastp].value) z[lastp].r=size;
194             else z[lastp].l=size;
195             splay(size,0);
196         }
197         swap(orz,size);
198     }
199     void replace(int v,int newv)
200     {
201         int now=root;
202         while (now)
203         {
204             if (z[now].value==v) break;
205             if (v>z[now].value) now=z[now].r;
206             else now=z[now].l;
207         }
208         if (z[now].r)
209         {
210             while (z[z[now].r].l)
211                 rot_r(z[now].r);
212             z[z[now].r].l=z[now].l;
213             z[z[now].l].f=z[now].r;
214             z[z[now].r].f=z[now].f;
215             if (now==root) root=z[now].r;
216             else 
217             {
218                 if (z[z[now].f].l==now) z[z[now].f].l=z[now].r;
219                 else z[z[now].f].r=z[now].r;
220             }
221             int orz=z[now].r;
222             while (orz)
223             {
224                 update(orz);
225                 orz=z[orz].f;
226             }
227         }
228         else
229         {
230             if (now==root) root=z[now].l;
231             else
232             {
233                 if (z[z[now].f].l==now) z[z[now].f].l=z[now].l;
234                 else z[z[now].f].r=z[now].l;
235             }
236             z[z[now].l].f=z[now].f;
237             int orz=z[now].f;
238             while (orz)
239             {
240                 update(orz);
241                 orz=z[orz].f;
242             }
243         }
244         size--;
245         insert(newv,now);
246     }
247     int get_rank(int v)
248     {
249         int now=root,ans=0;
250         while (now)
251         {
252             if (v>z[now].value) ans+=z[z[now].l].size+1,now=z[now].r;
253             else now=z[now].l;
254         }
255         return ans;
256     }
257     int get_rank2(int v)
258     {
259         int now=root,ans=0;
260         while (now)
261         {
262             if (v>=z[now].value) ans+=z[z[now].l].size+1,now=z[now].r;
263             else now=z[now].l;
264         }
265         return ans;
266     }
267     int query_pre(int v)
268     {
269         int ans=-INF,now=root;
270         while (now)
271         {
272             if (z[now].value<v) ans=max(ans,z[now].value),now=z[now].r;
273             else now=z[now].l;
274         }
275         return ans;
276     }
277     int query_next(int v)
278     {
279         int ans=INF,now=root;
280         while (now)
281         {
282             if (z[now].value>v) ans=min(ans,z[now].value),now=z[now].l;
283             else now=z[now].r;
284         }
285         return ans;
286     }
287 }tree[maxn<<2|1];
288 
289 void buildtree(int l,int r,int rt)
290 {
291     if (l==r)
292     {
293         scanf("%d",&z[l]);
294         min_num=min(min_num,z[l]);
295         max_num=max(max_num,z[l]);
296         tree[rt].build_z(sum);
297         tree[rt].insert(z[l],0);
298         sum+=2;
299         return;
300     }
301     int m=(l+r)>>1;
302     buildtree(lson);
303     buildtree(rson);
304     tree[rt].build_z(sum);
305     for (int a=l;a<=r;a++)
306         tree[rt].insert(z[a],0);
307     sum+=r-l+2;
308 }
309 
310 void changetree(int l,int r,int rt,int p,int v)
311 {
312     if (l==r)
313     {
314         tree[rt].replace(z[l],v);
315         lastv=z[l];
316         z[l]=v;
317         min_num=min(min_num,z[l]);
318         max_num=max(max_num,z[l]);
319         return;
320     }
321     int m=(l+r)>>1;
322     if (p<=m) changetree(lson,p,v);
323     else changetree(rson,p,v);
324     tree[rt].replace(lastv,v);
325 }
326 
327 int get_rank(int l,int r,int rt,int nowl,int nowr,int v)
328 {
329     if ((nowl<=l) && (r<=nowr)) return tree[rt].get_rank(v);
330     int m=(l+r)>>1;
331     int l_rank=0,r_rank=0;
332     if (nowl<=m) l_rank=get_rank(lson,nowl,nowr,v);
333     if (m<nowr) r_rank=get_rank(rson,nowl,nowr,v);
334     return l_rank+r_rank;
335 }
336 
337 int get_rank2(int l,int r,int rt,int nowl,int nowr,int v)
338 {
339     if ((nowl<=l) && (r<=nowr)) return tree[rt].get_rank2(v);
340     int m=(l+r)>>1;
341     int l_rank=0,r_rank=0;
342     if (nowl<=m) l_rank=get_rank2(lson,nowl,nowr,v);
343     if (m<nowr) r_rank=get_rank2(rson,nowl,nowr,v);
344     return l_rank+r_rank;
345 }    
346 
347 int query_pre(int l,int r,int rt,int nowl,int nowr,int v)
348 {
349     if ((nowl<=l) && (r<=nowr)) return tree[rt].query_pre(v);
350     int m=(l+r)>>1;
351     int l_pre=-INF,r_pre=-INF;
352     if (nowl<=m) l_pre=query_pre(lson,nowl,nowr,v);
353     if (m<nowr) r_pre=query_pre(rson,nowl,nowr,v);
354     return max(l_pre,r_pre);
355 }
356 
357 int query_next(int l,int r,int rt,int nowl,int nowr,int v)
358 {
359     if ((nowl<=l) && (r<=nowr)) return tree[rt].query_next(v);
360     int m=(l+r)>>1;
361     int l_next=INF,r_next=INF;
362     if (nowl<=m) l_next=query_next(lson,nowl,nowr,v);
363     if (m<nowr) r_next=query_next(rson,nowl,nowr,v);
364     return min(l_next,r_next);
365 }
366 
367 int main()
368 {
369     scanf("%d%d",&n,&m);
370     buildtree(1,n,1);
371     for (int a=1;a<=m;a++)
372     {
373         int order;
374         scanf("%d",&order);
375         switch(order)
376         {
377             case 1:
378                 {
379                     int l,r,k;
380                     scanf("%d%d%d",&l,&r,&k);
381                     printf("%d\n",get_rank(1,n,1,l,r,k)+1);
382                     break;
383                 }
384             case 2:
385                 {
386                     int l,r,k;
387                     scanf("%d%d%d",&l,&r,&k);
388                     int nowl=min_num-1,nowr=max_num;
389                     while (nowl+1!=nowr)
390                     {
391                         int m=(nowl+nowr)>>1;
392                         if (get_rank2(1,n,1,l,r,m)>=k) nowr=m;
393                         else nowl=m;
394                     }
395                     printf("%d\n",nowr);
396                     break;
397                 }
398             case 3:
399                 {
400                     int p,v;
401                     scanf("%d%d",&p,&v);
402                     changetree(1,n,1,p,v);
403                     break;
404                 }
405             case 4:
406                 {
407                     int l,r,k;
408                     scanf("%d%d%d",&l,&r,&k);
409                     printf("%d\n",query_pre(1,n,1,l,r,k));
410                     break;
411                 }
412             case 5:
413                 {
414                     int l,r,k;
415                     scanf("%d%d%d",&l,&r,&k);
416                     printf("%d\n",query_next(1,n,1,l,r,k));
417                     break;
418                 }
419         }
420     }
421 
422     return 0;
423 }
原文地址:https://www.cnblogs.com/zhonghaoxi/p/2515446.html