Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数
下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
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
我本来是不想先用这道题的,但是想想板子的重要性,我还是选择了这道题,此题仅仅是存板子
像这种真的就是套板子的题目,真的没有什么好讲的
这个板子不代表所有(还有恶心的区间操作)
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define MAXN 1000000 6 int ch[MAXN][2],f[MAXN],size[MAXN],cnt[MAXN],key[MAXN]; 7 int sz,root; 8 inline bool get(int x) 9 { 10 return ch[f[x]][1]==x; 11 } 12 void update(int x) 13 { 14 if (x){ 15 size[x]=cnt[x]; 16 if (ch[x][0]) size[x]+=size[ch[x][0]]; 17 if (ch[x][1]) size[x]+=size[ch[x][1]]; 18 } 19 } 20 void move(int now) 21 { 22 int fa=f[now],cnt=get(now),faa=f[fa]; 23 if(fa==root)root=now; 24 else if(faa)ch[faa][get(fa)]=now; 25 ch[fa][cnt]=ch[now][cnt^1]; 26 f[ch[now][cnt^1]]=fa; 27 ch[now][cnt^1]=fa; 28 f[fa]=now; 29 f[now]=faa; 30 update(fa),update(now); 31 } 32 void splay(int x,int &k) 33 { 34 int y,z; 35 while(x!=k) 36 { 37 y=f[x],z=f[y]; 38 if(y!=k) 39 { 40 if((ch[y][0]==ch[z][0])^(ch[y][1]==ch[z][1]))move(y); 41 else move(x); 42 } 43 move(x); 44 } 45 } 46 int find(int x) 47 { 48 int now=root,ans=0; 49 while(1) 50 { 51 if(x<key[now]) 52 now=ch[now][0]; 53 else 54 { 55 ans+=(ch[now][0]?size[ch[now][0]]:0); 56 if(x==key[now]){splay(now,root);return ans+1;} 57 ans+=cnt[now]; 58 now=ch[now][1]; 59 } 60 } 61 } 62 int findx(int x) 63 { 64 int now=root; 65 while(1) 66 { 67 if(ch[now][0]&&x<=size[ch[now][0]]) 68 now=ch[now][0]; 69 else 70 { 71 int w=(ch[now][0]?size[ch[now][0]]:0)+cnt[now]; 72 if (x<=w){return key[now];} 73 x-=w;now=ch[now][1]; 74 } 75 } 76 } 77 void inss(int m) 78 { 79 if(root==0){sz++;root=sz;key[sz]=m;cnt[sz]=1,size[sz]=1;return ;} 80 int now=root,fa=0; 81 while(1){ 82 if (m==key[now]){ 83 cnt[now]++; update(now); update(fa); splay(now,root); break; 84 } 85 fa=now; 86 now=ch[now][key[now]<m]; 87 if (now==0){ 88 sz++; 89 ch[sz][0]=ch[sz][1]=0; 90 f[sz]=fa; 91 size[sz]=cnt[sz]=1; 92 ch[fa][key[fa]<m]=sz; 93 key[sz]=m; 94 update(fa); 95 splay(sz,root); 96 break; 97 } 98 } 99 } 100 int pre() 101 { 102 int now=ch[root][0]; 103 while (ch[now][1])now=ch[now][1]; 104 return now; 105 } 106 int next() 107 { 108 int now=ch[root][1]; 109 while (ch[now][0])now=ch[now][0]; 110 return now; 111 } 112 void deel(int x) 113 { 114 int aa=find(x); 115 if(cnt[root]>1){cnt[root]--;return ;} 116 if (!ch[root][0]&&!ch[root][1]){root=0;return;} 117 if(ch[root][0]&&!ch[root][1]){root=ch[root][0];f[root]=0;return ;} 118 if(ch[root][1]&&!ch[root][0]){root=ch[root][1];f[root]=0;return ;} 119 int old=pre();int rt=root; 120 splay(old,root); 121 f[ch[rt][1]]=root; 122 ch[root][1]=ch[rt][1]; 123 update(root); 124 } 125 int main(){ 126 int n,opt,x; 127 scanf("%d",&n); 128 for (int i=1;i<=n;++i){ 129 scanf("%d%d",&opt,&x); 130 switch(opt){ 131 case 1: inss(x); break; 132 case 2: deel(x); break; 133 case 3: printf("%d\n",find(x)); break; 134 case 4: printf("%d\n",findx(x)); break; 135 case 5: inss(x);printf("%d\n",key[pre()]);deel(x);break; 136 case 6: inss(x); printf("%d\n",key[next()]);deel(x);break; 137 } 138 } 139 }