模板:fhq treap
普通平衡树:
支持的操作是:
序列中插入或删除价值为x的数
查询价值为x的排名 或者排名对应的价值
查询价值的前驱后继
#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;
const int N=100010;
int read()
{
int x=0,f=0,c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return f?-x:x;
}
int sz[N],val[N],rnd[N],lch[N],rch[N];
int root,rx,ry,rz,cnt;
void upd(int x){ sz[x]=sz[lch[x]]+sz[rch[x]]+1;}
void split(int now,int k,int &x,int &y)
{
if(!now){ x=y=0; return;}
if(k>=val[now]) x=now,split(rch[now],k,rch[x],y);
else y=now,split(lch[now],k,x,lch[y] );
upd(now);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(rnd[x]<rnd[y]){ rch[x]=merge(rch[x],y); upd(x); return x;}
else { lch[y]=merge(x,lch[y]); upd(y); return y;}
}
int find(int k,int rt)
{
int now=rt;
while(1)
{
int lsz=sz[lch[now]],rsz=sz[rch[now]];
if(k==lsz+1) return now;
else if(k<=lsz) now=lch[now];
else now=rch[now],k-=(lsz+1);//这个地方要+1
}
}
int _new(int x)
{
sz[++cnt]=1; val[cnt]=x; rnd[cnt]=rand();
return cnt;
}
int main()
{
srand( (unsigned) time(0));
int n=read(),m=read();
for(int i=1;i<=n;i++) insert( read() );
while(m--)
{
int opt=read(),x=read();
if(opt==1)
{
split(root,x-1,rx,ry);
root=merge( merge(rx,_new(x)),ry );
}
else if(opt==2)
{
split(root,x,rx,rz);
split(rx,x-1,rx,ry);
root=merge( merge( rx, merge(lch[ry],rch[ry]) ), rz );
}
else if(opt==3)
{
split(root,x-1,rx,ry);
printf("%d\n",sz[rx]+1);
root=merge(rx,ry);//分裂之后要合并回去
}
else if(opt==4) printf("%d\n",val[find(x,root)]);
else if(opt==5)
{
split(root,x-1,rx,ry);
printf("%d\n",val[find(sz[rx],rx)]);// 套上val
root=merge(rx,ry);
}
else if(opt==6)
{
split(root,x,rx,ry);
printf("%d\n",val[find(1,ry)]);
root=merge(rx,ry);
}
}
}

浙公网安备 33010602011771号