FHQ Treap学习

安利一下blog,看一下:https://www.luogu.org/blog/Chanis/fhq-treap

code:

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<cmath>
const int maxn=500006;
int n,m,q,x,y,z,cnt;
int size[maxn],ch[maxn][3],val[maxn],rnd[maxn],root;
inline int creat(int k)
{
	size[++cnt]=1;
	val[cnt]=k;
	rnd[cnt]=rand();
	return cnt;
}
inline void update(int s)
{
	size[s]=size[ch[s][0]]+size[ch[s][1]]+1;
}
inline void split(int now,int &x,int &y,int k)
{
	if (!now) 
	{
		x=y=0;
		return;
	}
	if (val[now]<=k)
	{
		x=now,split(ch[now][1],ch[now][1],y,k);
	}
	else 
	{
		y=now,split(ch[now][0],x,ch[now][0],k);
	}
	update(now);
} 
inline int merge(int a,int b)
{
	if (!a||!b) return a+b;
	if (rnd[a]<rnd[b])
	{
		ch[a][1]=merge(ch[a][1],b);
		update(a);
		return a;
	}
	else 
	{
		ch[b][0]=merge(a,ch[b][0]);
		update(b);
		return b;
	}
}
inline void insert(int k)
{
	int cur=creat(k);
	split(root,x,y,k);
	root=merge(merge(x,cur),y);
}
inline void del(int k)
{
		split(root,x,z,k);
		split(x,x,y,k-1);
		y=merge(ch[y][0],ch[y][1]);
		root=merge(merge(x,y),z);//记得要先merge起x,y 
}
inline int find_k(int s,int k)
{
	for (;;)
	{
		if (size[ch[s][0]]>=k) s=ch[s][0]; //(注意是比较儿子的size,因为可能有一样的数)
		else if (k==size[ch[s][0]]+1) return s;
		else
		{
			k-=size[ch[s][0]]+1;
			s=ch[s][1];	
		} 
	}
}
inline int pre(int s,int k)
{
	split(s,x,y,k-1);
	int tmp=val[find_k(x,size[x])];
	root=merge(x,y);
	return tmp;
}
inline int nxt(int s,int k)
{
	split(s,x,y,k);
	int tmp=val[find_k(y,1)];
	root=merge(x,y);
	return tmp;
}
inline void cout(int k) 
{
	printf("%d\n",k);
}
int main()
{
	srand((unsigned)(time(NULL)));
	std::cin>>m;
	for (int i=1,q1,q2;i<=m;++i)
	{
		scanf("%d%d",&q1,&q2);
		if (q1==1) 
		{
			int cur=creat(q2);
			split(root,x,y,q2);
			root=merge(merge(x,cur),y);
		}
		if (q1==2) 
		{
			split(root,x,z,q2);
            split(x,x,y,q2-1);
            y=merge(ch[y][0],ch[y][1]);
            root=merge(merge(x,y),z);
//            del(q2);
		}
		if (q1==3) 
		{
			split(root,x,y,q2-1);
			cout(size[x]+1);
			root=merge(x,y);
		}
		if (q1==4) cout(val[find_k(root,q2)]);
		if (q1==5) cout(pre(root,q2));
		if (q1==6) cout(nxt(root,q2));
	}
	return 0;
}
posted @ 2018-09-04 19:12  Splitor  阅读(166)  评论(0编辑  收藏  举报