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]
Source
此题我用了splay来维护。数据不会卡。。可能很水吧。。
Code:
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int Tcnt=0,root=0;
int nn[N];
struct Ty{
int son[2],sz,pre,sum;
}tree[N];
void up(int u){
tree[u].sz=1+tree[tree[u].son[0]].sz+tree[tree[u].son[1]].sz;
}
void Rotate(int x,int f){
int y=tree[x].pre;
tree[y].son[!f]=tree[x].son[f];
tree[tree[x].son[f]].pre=y;
tree[x].pre=tree[y].pre;
if (tree[x].pre) tree[tree[y].pre].son[(tree[tree[y].pre].son[1]==y)]=x;
tree[x].son[f]=y;
tree[y].pre=x;
up(x); up(y);
}
void splay(int x,int goal){
while (tree[x].pre!=goal){
if (tree[tree[x].pre].pre==goal) Rotate(x,tree[tree[x].pre].son[0]==x);
else{
int y=tree[x].pre,z=tree[y].pre;
int f=(tree[z].son[0]==y);
if (tree[y].son[f]==x) Rotate(x,!f),Rotate(x,f);
else Rotate(y,f),Rotate(x,f);
}
}
up(x);
if (!goal) root=x;
}
void insert(int i,int x){
nn[i]=x;
int z=0,y=root;
while (y){
z=y;
y=tree[y].son[(nn[i]>=nn[y])];
}
tree[i].pre=z;
if (!z) root=i;
else tree[z].son[(nn[i]>=nn[z])]=i;
up(i); z=tree[i].pre;
while (z) up(z),z=tree[z].pre;
}
int find(int x){
int i=root;
while (nn[i]!=x){
if (nn[i]<=x) i=tree[i].son[1];
else i=tree[i].son[0];
}
return i;
}
void delet(int x){
int j,i=find(x);
while (tree[i].son[0] || tree[i].son[1]){
if (!tree[i].son[0]) j=tree[i].son[1];
else j=tree[i].son[0];
splay(j,tree[i].pre);
}
j=tree[i].pre;
tree[tree[i].pre].son[tree[tree[i].pre].son[1]==i]=0;
tree[i].pre=0;
tree[i].son[0]=tree[i].son[1]=0;
tree[i].sz=0;
while (j) up(j),j=tree[j].pre;
}
int rank(int x){
int y=root,z=0;
while (1){
if (!y) return 0;
if (nn[y]==x) return tree[tree[y].son[0]].sz+1+z;
if (nn[y]>x) y=tree[y].son[0];
else z+=tree[tree[y].son[0]].sz+1,y=tree[y].son[1];
}
}
int nrank(int x){
int z=root;
while (x){
int k=tree[tree[z].son[0]].sz;
if (x==k+1) return nn[z];
if (x<=k) z=tree[z].son[0];
else z=tree[z].son[1],x-=k+1;
}
return nn[z];
}
int prre(int x){
int y=root,z=0;
while (1){
if (!y) return nn[z];
if (nn[y]>=x) y=tree[y].son[0];
else{
z=y;
y=tree[y].son[1];
}
}
}
int neext(int x){
int y=root,z=0;
while (1){
if (!y) return nn[z];
if (nn[y]>x){
if (nn[y]!=x) z=y;
y=tree[y].son[0];
} else y=tree[y].son[1];
}
}
int main(){
int n;Tcnt=0;
scanf("%d",&n);
while (n--){
int opt,x;
scanf("%d%d",&opt,&x);
if (opt==1) insert(++Tcnt,x);
if (opt==2) delet(x);
if (opt==3) printf("%d\n",rank(x));
if (opt==4) printf("%d\n",nrank(x));
if (opt==5) printf("%d\n",prre(x));
if (opt==6) printf("%d\n",neext(x));
}
return 0;
}