#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100005
int siz[maxn],key[maxn],L[maxn],R[maxn];
int n,rt,tot;
void right_rotate(int &rt)
{
int k=L[rt];
L[rt]=R[k];
R[k]=rt;
siz[k]=siz[rt];
siz[rt]=siz[L[rt]]+siz[R[rt]]+1;
rt=k;
}
void left_rotate(int &rt)
{
int k=R[rt];
R[rt]=L[k];
L[k]=rt;
siz[k]=siz[rt];
siz[rt]=siz[L[rt]]+siz[R[rt]]+1;
rt=k;
}
void maintain(int &rt,bool flag)
{
if (flag==0)
{
if (siz[L[L[rt]]]>siz[R[rt]]) right_rotate(rt);
else if (siz[R[L[rt]]]>siz[R[rt]])
{
left_rotate(L[rt]);
right_rotate(rt);
}
else return;
}
else
{
if (siz[R[R[rt]]]>siz[L[rt]]) left_rotate(rt);
else if (siz[L[R[rt]]]>siz[L[rt]])
{
right_rotate(R[rt]);
left_rotate(rt);
}
else return;
}
maintain(L[rt],0);
maintain(R[rt],1);
maintain(rt,1);
maintain(rt,0);
}
void insert(int &rt,int v)
{
if (rt==0)
{
tot++;
siz[tot]=1;
key[tot]=v;
rt=tot;
}
else
{
siz[rt]++;
if (v<key[rt]) insert(L[rt],v);
else insert(R[rt],v);
maintain(rt,v>=key[rt]);
}
}
int dele(int &rt,int v)
{
int d;
siz[rt]--;
if (key[rt]==v||(key[rt]<v&&R[rt]==0)||(key[rt]>v&&L[rt]==0))
{
d=key[rt];
if (L[rt]==0||R[rt]==0) rt=L[rt]+R[rt];
else key[rt]=dele(L[rt],v+1);
}
else
{
if (v>key[rt]) d=dele(R[rt],v);
else d=dele(L[rt],v);
}
return d;
}
int rank(int &rt,int v)
{
int r;
if (rt==0) return 1;
if (v<=key[rt]) r=rank(L[rt],v);
else r=rank(R[rt],v)+siz[L[rt]]+1;
return r;
}
int select(int &rt,int k)
{
int s;
if (k<siz[L[rt]]+1) s=select(L[rt],k);
if (k==siz[L[rt]]+1) s=key[rt];
if (k>siz[L[rt]]+1) s=select(R[rt],k-siz[L[rt]]-1);
return s;
}
int pred(int &rt,int v)
{
int p;
if (rt==0) return -1;
if (key[rt]>=v) p=pred(L[rt],v);
else
{
p=pred(R[rt],v);
if (p==-1) p=key[rt];
}
return p;
}
int succ(int &rt,int v)
{
int s;
if (rt==0) return -1;
if (key[rt]<=v) s=succ(R[rt],v);
else
{
s=succ(L[rt],v);
if (s==-1) s=key[rt];
}
return s;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
int a,opt;
scanf("%d%d",&opt,&a);
if (opt==1) insert(rt,a);
if (opt==2) dele(rt,a);
if (opt==3) printf("%d\n",rank(rt,a));
if (opt==4) printf("%d\n",select(rt,a));
if (opt==5) printf("%d\n",pred(rt,a));
if (opt==6) printf("%d\n",succ(rt,a));
}
return 0;
}
平衡树SBT模板
最新推荐文章于 2021-10-24 08:58:38 发布