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每行輸出一個數,表示對應答案
二叉平衡樹模闆題,splay版。
treap版見http://blog.csdn.net/sdfzyhx/article/details/51418974。
替罪羊樹版見http://blog.csdn.Net/sdfzyhx/article/details/70212142。
#include<cstdio>
#include<cstring>
struct node
{
int f,c[2],x,size,cnt;
}t[100010];
int root,size;
void up(int p)
{
t[p].size=t[t[p].c[0]].size+t[t[p].c[1]].size+t[p].cnt;
}
void rot(int p,bool b)
{
int x=t[p].f;
int y=t[p].c[b];
int z=t[y].c[!b];
t[x].c[t[x].c[0]!=p]=y;
if (y)
t[y].f=x;
t[y].c[!b]=p;
if (p)
t[p].f=y;
t[p].c[b]=z;
if (z)
t[z].f=p;
up(p);
up(y);
}
void splay(int p)
{
int x=t[p].f;
int y=t[x].f;
if (!x) return;
if (!y)
{
rot(x,t[x].c[0]!=p);
return;
}
if ((t[x].c[0]==p)^(t[y].c[0]==x))
rot(x,t[x].c[0]!=p),rot(y,t[y].c[0]!=p),splay(p);
else
rot(y,t[y].c[0]!=x),rot(x,t[x].c[0]!=p),splay(p);
}
void ins(int p,int x,int f,bool b)
{
if (p==0)
{
p=++size;
t[f].c[b]=p;
t[p].f=f;
t[p].x=x;
t[p].size=t[p].cnt=1;
splay(p);
return;
}
t[p].size++;
if (t[p].x==x)
{
t[p].cnt++;
splay(p);
return;
}
ins(t[p].c[x>t[p].x],x,p,x>t[p].x);
}
void del(int p,int x,int f,int b)
{
if (t[p].x==x)
{
if (t[p].cnt>1)
{
t[p].size--;
t[p].cnt--;
return;
}
if (t[p].c[0]==0&&t[p].c[1]==0)
{
t[f].c[b]=0;
return;
}
if (t[p].c[0]*t[p].c[1]==0)
{
t[f].c[b]=t[p].c[0]+t[p].c[1];
if (t[p].c[0])
t[t[p].c[0]].f=f;
else
t[t[p].c[1]].f=f;
return;
}
rot(p,t[t[p].c[1]].size<t[t[p].c[0]].size);
t[t[p].f].size--;
del(p,x,t[p].f,t[t[p].f].c[0]!=p);
return;
}
t[p].size--;
del(t[p].c[x>t[p].x],x,p,x>t[p].x);
}
int ran(int p,int x)
{
if (p==0) return 0;
if (x<t[p].x) return ran(t[p].c[0],x);
if (x==t[p].x)
{
int ans=t[t[p].c[0]].size+1;
splay(p);
return ans;
}
return t[t[p].c[0]].size+t[p].cnt+ran(t[p].c[1],x);
}
int que(int p,int x)
{
if (p==0) return 0;
if (x<=t[t[p].c[0]].size) return que(t[p].c[0],x);
if (x<=t[t[p].c[0]].size+t[p].cnt)
{
splay(p);
return t[p].x;
}
return que(t[p].c[1],x-t[t[p].c[0]].size-t[p].cnt);
}
int pre(int p,int x)
{
if (p==0) return -1;
if (t[p].x<x)
{
int y=pre(t[p].c[1],x);
if (y==-1)
{
splay(p);
return t[p].x;
}
return y;
}
return pre(t[p].c[0],x);
}
int suc(int p,int x)
{
if (p==0) return -1;
if (t[p].x>x)
{
int y=suc(t[p].c[0],x);
if (y==-1)
{
splay(p);
return t[p].x;
}
return y;
}
return suc(t[p].c[1],x);
}
int main()
{
int i,j,k,x,y,n;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
if (x==1) ins(t[0].c[0],y,0,0);
if (x==2) del(t[0].c[0],y,0,0);
if (x==3) printf("%d\n",ran(t[0].c[0],y));
if (x==4) printf("%d\n",que(t[0].c[0],y));
if (x==5) printf("%d\n",pre(t[0].c[0],y));
if (x==6) printf("%d\n",suc(t[0].c[0],y));
}
}