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
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
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
题解
平衡树的模版题,用来存模版了。
1、Treap
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdlib> 5 #define maxn 100005 6 #define inf 1<<29 7 using namespace std; 8 int cnt,ret,n,root; 9 struct treap{int lc,rc,key,pri,siz,val;}a[maxn]; 10 void pushup(int o){a[o].siz=a[a[o].lc].siz+a[a[o].rc].siz+a[o].val;} 11 void rturn(int &o) 12 { 13 int t=a[o].lc; 14 a[o].lc=a[t].rc; 15 a[t].rc=o; 16 a[t].siz=a[o].siz; 17 pushup(o); 18 o=t; 19 return ; 20 } 21 void lturn(int &o) 22 { 23 int t=a[o].rc; 24 a[o].rc=a[t].lc; 25 a[t].lc=o; 26 a[t].siz=a[o].siz; 27 pushup(o); 28 o=t; 29 return ; 30 } 31 void insert(int &o,int x) 32 { 33 if(!o) 34 { 35 o=++cnt; 36 a[o]=(treap){0,0,x,rand(),1,1}; 37 return ; 38 } 39 ++a[o].siz; 40 if(x==a[o].key)++a[o].val; 41 else if(x<a[o].key){insert(a[o].lc,x);if(a[a[o].lc].pri>a[o].pri)rturn(o);} 42 else{insert(a[o].rc,x);if(a[a[o].rc].pri>a[o].pri)lturn(o);} 43 } 44 void del(int &o,int x) 45 { 46 if(!o)return ; 47 if(x==a[o].key) 48 { 49 if(a[o].val>1)a[o].val--,a[o].siz--; 50 else if(!(a[o].lc*a[o].rc))o=a[o].lc+a[o].rc; 51 else 52 { 53 if(a[a[o].lc].pri>a[a[o].rc].pri){rturn(o);del(o,x);} 54 else{lturn(o);del(o,x);} 55 } 56 } 57 else if(x<a[o].key){a[o].siz--;del(a[o].lc,x);} 58 else {a[o].siz--;del(a[o].rc,x);} 59 } 60 int que_rank(int o,int x) 61 { 62 if(!o)return 0; 63 if(x<a[o].key)return que_rank(a[o].lc,x); 64 if(x==a[o].key)return a[a[o].lc].siz+1; 65 return a[a[o].lc].siz+a[o].val+que_rank(a[o].rc,x); 66 } 67 int que_num(int o,int x) 68 { 69 if(!o)return 0; 70 if(x<=a[a[o].lc].siz)return que_num(a[o].lc,x); 71 if(x<=a[a[o].lc].siz+a[o].val)return a[o].key; 72 return que_num(a[o].rc,x-a[a[o].lc].siz-a[o].val); 73 } 74 void que_pro(int o,int x) 75 { 76 if(!o)return ; 77 if(x<=a[o].key)que_pro(a[o].lc,x); 78 else {ret=a[o].key;que_pro(a[o].rc,x);} 79 } 80 void que_sub(int o,int x) 81 { 82 if(!o)return ; 83 if(x>=a[o].key)que_sub(a[o].rc,x); 84 else {ret=a[o].key;que_sub(a[o].lc,x);} 85 } 86 int main() 87 { 88 scanf("%d",&n); 89 srand(n); 90 for(int i=1 ; i<=n ; ++i) 91 { 92 int a,b; 93 scanf("%d%d",&a,&b); 94 if(a==1)insert(root,b); 95 else if(a==2)del(root,b); 96 else if(a==3)printf("%d\n",que_rank(root,b)); 97 else if(a==4)printf("%d\n",que_num(root,b)); 98 else if(a==5) 99 { 100 ret=-inf; 101 que_pro(root,b); 102 printf("%d\n",ret); 103 } 104 else 105 { 106 ret=inf; 107 que_sub(root,b); 108 printf("%d\n",ret); 109 } 110 } 111 return 0; 112 }