您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
对于操作3,4,5,6每行输出一个数,表示对应答案
正解:平衡树。
这题就是平衡树,各种平衡树都能写。。今天晚上学了学替罪羊树,我能说我调了一晚上的原因是因为insert的传址问题吗。。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define N (100010) 15 #define il inline 16 #define RG register 17 #define ll long long 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 19 20 using namespace std; 21 22 int ch[N][2],cover[N],sz[N],val[N],del[N],st[N],Q,rt,top,tot; 23 const double alpha=0.75; 24 25 il int gi(){ 26 RG int x=0,q=1; RG char ch=getchar(); while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 27 if (ch==‘-‘) q=-1,ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return q*x; 28 } 29 30 il void pushup(RG int x){ 31 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+(!del[x]); 32 cover[x]=cover[ch[x][0]]+cover[ch[x][1]]+1; return; 33 } 34 35 il void dfs(RG int x){ 36 if (ch[x][0]) dfs(ch[x][0]); 37 if (!del[x]) st[++top]=x; 38 if (ch[x][1]) dfs(ch[x][1]); 39 sz[x]=cover[x]=ch[x][0]=ch[x][1]=0; 40 return; 41 } 42 43 il int divide(RG int l,RG int r){ 44 if (l>r) return 0; RG int mid=(l+r)>>1; 45 ch[st[mid]][0]=divide(l,mid-1); 46 ch[st[mid]][1]=divide(mid+1,r); 47 pushup(st[mid]); return st[mid]; 48 } 49 50 il void rebuild(RG int &x){ top=0,dfs(x),x=divide(1,top); return; } 51 52 il int qrank(RG int x,RG int k){ 53 RG int res=1; 54 while (x){ 55 if (k<=val[x]) x=ch[x][0]; 56 else res+=sz[ch[x][0]]+(!del[x]),x=ch[x][1]; 57 } 58 return res; 59 } 60 61 il int find(RG int x,RG int k){ 62 while (x){ 63 if (!del[x] && k==sz[ch[x][0]]+1) return val[x]; 64 if (k<=sz[ch[x][0]]) x=ch[x][0]; 65 else k-=sz[ch[x][0]]+(!del[x]),x=ch[x][1]; 66 } 67 return val[x]; 68 } 69 70 il int* Insert(RG int &x,RG int k){ 71 if (!x){ val[x=++tot]=k,sz[x]=cover[x]=1; return NULL; } 72 sz[x]++,cover[x]++; int *p=Insert(ch[x][val[x]<=k],k); 73 if (max(cover[ch[x][0]],cover[ch[x][1]])>cover[x]*alpha) p=&x; 74 return p; 75 } 76 77 il void insert(RG int k){ int *x=Insert(rt,k); if (x) rebuild(*x); return; } 78 79 il void Erase(RG int x,RG int k){ 80 while (x){ 81 sz[x]--; if (!del[x] && k==sz[ch[x][0]]+1){ del[x]=1; return; } 82 if (k<=sz[ch[x][0]]) x=ch[x][0]; else k-=sz[ch[x][0]]+(!del[x]),x=ch[x][1]; 83 } 84 return; 85 } 86 87 il void erase(RG int k){ Erase(rt,qrank(rt,k)); if (sz[rt]<cover[rt]*alpha) rebuild(rt); return; } 88 89 il void work(){ 90 Q=gi(); RG int type,x; 91 while (Q--){ 92 type=gi(),x=gi(); 93 if (type==1) insert(x); 94 if (type==2) erase(x); 95 if (type==3) printf("%d\n",qrank(rt,x)); 96 if (type==4) printf("%d\n",find(rt,x)); 97 if (type==5) printf("%d\n",find(rt,qrank(rt,x)-1)); 98 if (type==6) printf("%d\n",find(rt,qrank(rt,x+1))); 99 } 100 return; 101 } 102 103 int main(){ 104 File("tree"); 105 work(); 106 return 0; 107 }
原文:http://www.cnblogs.com/wfj2048/p/6498757.html