由于其他部分拷的其他平衡树的代码,应该是仅 merge,split,insert,erase
可能出错。
#include<cctype>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=1e5;
int n,opt,x,root,total,BST[maxn+1],child[maxn+1][2],size[maxn+1],times[maxn+1],priority[maxn+1];
inline void read(int &x)
{
x=0;
int signum=1;
char t=getchar();
while(!isdigit(t))
{
if(t=='-')
signum=-1;
t=getchar();
}
while(isdigit(t))
{
x=x*10+t-'0';
t=getchar();
}
x*=signum;
return;
}
inline void pushup(int now)
{
size[now]=size[child[now][0]]+size[child[now][1]]+times[now];
return;
}
int merge(int x,int y)
{
if(!x||!y)
return x+y;
int now=0;
if(priority[x]<priority[y])
child[now=x][1]=merge(child[x][1],y);
else child[now=y][0]=merge(x,child[y][0]);
pushup(now);
return now;
}
void split(int now,int &x,int &y,int value)
{
if(!now)
{
x=y=0;
return;
}
if(BST[now]<value)
split(child[x=now][1],child[now][1],y,value);
else split(child[y=now][0],x,child[now][0],value);
pushup(now);
return;
}
void insert(int target)
{
int x=0,y=0;
split(root,x,y,target);
if(BST[y]==target)
{
++times[y];
root=merge(x,y);
}
else
{
int now=++total;
times[now]=size[now]=1;
priority[now]=rand();
BST[now]=target;
root=merge(x,merge(now,y));
}
return;
}
void erase(int target)
{
int x=0,y=0,z=0;
split(root,x,y,target);
split(y,y,z,target+1);
if(times[y]>1)
{
--times[y];
root=merge(x,merge(y,z));
}
else root=merge(x,z);
return;
}
int rank_of(int target)
{
int now=root,res=0;
while(now)
if(target==BST[now])
return res+size[child[now][0]]+1;
else if(target<BST[now])
now=child[now][0];
else
{
res+=size[child[now][0]]+times[now];
now=child[now][1];
}
return res+1;
}
int at(int target)
{
int now=root;
while(now)
if(size[child[now][0]]<target&&size[child[now][0]]+times[now]>=target)
return BST[now];
else if(size[child[now][0]]>=target)
now=child[now][0];
else
{
target-=size[child[now][0]]+times[now];
now=child[now][1];
}
return -1;
}
int predecessor(int target)
{
int res=0;
for(int i=root;i;i=child[i][target>BST[i]])
if(target>BST[i])
res=i;
return res?BST[res]:-0x7fffffff;
}
int successor(int target)
{
int res=0;
for(int i=root;i;i=child[i][target>=BST[i]])
if(target<BST[i])
res=i;
return res?BST[res]:0x7fffffff;
}
int main()
{
read(n);
for(int i=1;i<=n;++i)
{
read(opt);
read(x);
if(opt==1)
insert(x);
else if(opt==2)
erase(x);
else if(opt==3)
printf("%d\n",rank_of(x));
else if(opt==4)
printf("%d\n",at(x));
else if(opt==5)
printf("%d\n",predecessor(x));
else printf("%d\n",successor(x));
}
return 0;
}