bzoj 3224: Tyvj 1728 普通平衡树

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

 

1.n的数据范围:n<=100000

2.每个数的数据范围:[-2e9,2e9]
 
这是平衡树的入门题了,可以有很多种写法:  
 
1.权值线段树 
2.treap
3. splay
4.替罪羊树
5.fhq treap (可持久化treap)  
 
附录: 可持久化平衡树代码
 1 #include<bits/stdc++.h>
 2 using namespace std; 
 3 int const N=100000+10;  
 4 int n,val[N],key[N],ch[N][2],sz[N],root,rb[N],top; 
 5 void update(int x){
 6     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;  
 7 }
 8 int mr(int k){
 9     int x=rb[top--];val[x]=k;sz[x]=1;ch[x][0]=ch[x][1]=0;key[x]=rand(); return x; 
10 }     
11 int getkth(int x,int k){
12     while (x){
13         if(sz[ch[x][0]]>=k) x=ch[x][0];  
14         else if(sz[ch[x][0]]+1==k) return val[x];  
15         else k-=sz[ch[x][0]]+1,x=ch[x][1];  
16     }
17 }
18 void split(int now,int k,int &x,int &y){
19     if(!now) x=y=0;  
20     else {
21         if(val[now]<=k) 
22             x=now,split(ch[now][1],k,ch[now][1],y);  
23         else 
24             y=now,split(ch[now][0],k,x,ch[now][0]);    
25         update(now);   
26     }
27 }
28 int merge(int x,int y){
29     if(!x || !y) return x+y;  
30     if(key[x]<key[y]) {
31         ch[x][1]=merge(ch[x][1],y); 
32         update(x);  
33         return x;     
34     }else {
35         ch[y][0]=merge(x,ch[y][0]); 
36         update(y);   
37         return y;  
38     }
39 }
40 int main(){
41     int x,y,z,opt,k;  
42     scanf("%d",&n); 
43     for(int i=1;i<=n;i++) rb[i]=n-i+1;   
44     top=n;  
45     while (n--){
46         scanf("%d%d",&opt,&k);  
47         if(opt==1){
48             split(root,k,x,y);  
49             root=merge(merge(x,mr(k)),y);  
50         }
51         if(opt==2){
52             split(root,k,x,y);  
53             split(x,k-1,x,z);
54             rb[++top]=z;   
55             z=merge(ch[z][0],ch[z][1]);  
56             root=merge(merge(x,z),y);   
57         }
58         if(opt==3){
59             split(root,k-1,x,y);  
60             printf("%d\n",sz[x]+1); 
61             root=merge(x,y);  
62         }
63         if(opt==4){
64             printf("%d\n",getkth(root,k));      
65         }
66         if(opt==5){
67             split(root,k-1,x,y);  
68             printf("%d\n",getkth(x,sz[x])); 
69             root=merge(x,y);    
70         } 
71         if(opt==6){
72             split(root,k,x,y);  
73             printf("%d\n",getkth(y,1));
74             root=merge(x,y);    
75         }
76     }
77     return 0;  
78 }
View Code

 

posted @ 2019-09-03 19:36  zjxxcn  阅读(160)  评论(0编辑  收藏  举报