模板: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);
		}
	}
}
posted @ 2021-12-29 18:53  __iostream  阅读(27)  评论(0)    收藏  举报