题目地址 http://www.lydsy.com/JudgeOnline/problem.php?id=3224
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]
Treap膜版题
几个变量打错交到怀疑人生,做题的时候bzoj奇卡无比
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 8 int read(){ 9 bool flag=0; 10 char ch; 11 int re=0; 12 while((ch=getchar())!='-'&&(ch<'0'||ch>'9')); 13 ch=='-'?flag=1:re=ch-'0'; 14 while((ch=getchar())>='0'&&ch<='9') re=re*10+ch-'0'; 15 return flag?-re:re; 16 } 17 18 void write(int re){ 19 if(re<0){ 20 putchar('-'); 21 re=-re; 22 } 23 if(re>=10) write(re/10); 24 putchar(re%10+'0'); 25 } 26 27 const int maxn=1e5+5; 28 struct Splay{ 29 int v,w,size,rnd; 30 int l,r; 31 Splay(int v=0,int w=0,int size=0,int rnd=0,int l=0,int r=0): 32 v(v),w(w),size(size),rnd(rnd),l(l),r(r){} 33 }t[maxn]; 34 int cnt=0,root; 35 36 inline void update(int x){ t[x].size=t[t[x].l].size+t[t[x].r].size+t[x].w; } 37 38 inline void rturn(int &x){ 39 int c=t[x].l; t[x].l=t[c].r; t[c].r=x; 40 t[c].size=t[x].size; update(x); x=c; 41 } 42 43 inline void lturn(int &x){ 44 int c=t[x].r; t[x].r=t[c].l; t[c].l=x; 45 t[c].size=t[x].size; update(x); x=c; 46 } 47 48 void ins(int &x,int v){ 49 if(x==0){ 50 cnt++; x=cnt; 51 t[cnt]=Splay(v,1,1,rand(),0,0); 52 return; 53 } 54 t[x].size++; 55 if(t[x].v==v){ t[x].w++; return; } 56 if(v<t[x].v){ 57 ins(t[x].l,v); 58 if(t[t[x].l].rnd<t[x].rnd) rturn(x); 59 } 60 else{ 61 ins(t[x].r,v); 62 if(t[t[x].r].rnd<t[x].rnd) lturn(x); 63 } 64 } 65 66 void del(int &x,int v){ 67 if(x==0) return; 68 if(t[x].v==v){ 69 if(t[x].w>1){ t[x].w--; t[x].size--; return; } 70 if(t[x].l*t[x].r==0) x=t[x].l+t[x].r; 71 else 72 if(t[t[x].l].rnd < t[t[x].r].rnd){ rturn(x); del(x,v); } 73 else{ lturn(x); del(x,v); } 74 } 75 else{ 76 t[x].size--; 77 if(v<t[x].v) del(t[x].l,v); 78 else del(t[x].r,v); 79 } 80 } 81 82 int rnk(int x,int v){ 83 if(t[x].v==v) return t[t[x].l].size+1; 84 if(v<t[x].v) return rnk(t[x].l,v); 85 else return t[t[x].l].size+t[x].w+rnk(t[x].r,v); 86 } 87 88 int kth(int x,int k){ 89 if(x==0) return 0; 90 if(k<=t[t[x].l].size) return kth(t[x].l,k); 91 else if(k>t[t[x].l].size+t[x].w) return kth(t[x].r,k-t[t[x].l].size-t[x].w); 92 else return t[x].v; 93 } 94 95 int ans; 96 97 void pre(int x,int v){ 98 if(x==0) return; 99 if(v>t[x].v){ ans=x; pre(t[x].r,v); } 100 else pre(t[x].l,v); 101 } 102 103 void suf(int x,int v){ 104 if(x==0) return; 105 if(v<t[x].v){ ans=x; suf(t[x].l,v); } 106 else suf(t[x].r,v); 107 } 108 109 int main(){ 110 //freopen("temp.in","r",stdin); 111 srand(222); 112 int n=read(); 113 while(n--){ 114 int op=read(),x=read(); 115 switch(op){ 116 case 1:ins(root,x); break; 117 case 2:del(root,x); break; 118 case 3:write(rnk(root,x)); putchar(' '); break; 119 case 4:write(kth(root,x)); putchar(' '); break; 120 case 5:ans=0; pre(root,x); write(t[ans].v); putchar(' '); break; 121 case 6:ans=0; suf(root,x); write(t[ans].v); putchar(' '); break; 122 } 123 } 124 return 0; 125 }