「模板」 可持久化平衡树

「模板」 可持久化平衡树

<题目链接>


(There's suddenly something wrong with my Chinese Input Method...)

Persistable FHQ_Treap.

MLE 2 points after debugging for a whole evening for the pointers.

At last I chose to use array.

Although AC, upset.

#include <climits>
#include <cstdio>
#include <cstdlib>
const int MAXN=500010;
int n;
class FHQ_Treap
{
	public:
		FHQ_Treap(void):cnt(0)
		{
			rt[0]=0;
		}
		void Copy(int i,int j)
		{
			rt[i]=rt[j];
		}
		void Insert(int i,int x)
		{
			int l,r,t=NewNode(x);
			Split(rt[i],x,l,r);
			Merge(l,l,t);
			Merge(rt[i],l,r);
		}
		void Delete(int i,int x)
		{
			int l,r,t;
			Split(rt[i],x,l,r);
			Split(l,x-1,l,t);
			Merge(t,s[t].c[0],s[t].c[1]);
			Merge(l,l,t);
			Merge(rt[i],l,r);
		}
		void Rank(int i,int x)
		{
			int l,r;
			Split(rt[i],x-1,l,r);
			printf("%d
",s[l].size+1);
			Merge(rt[i],l,r);
		}
		void Find(int i,int x)
		{
			printf("%d
",FindKth(rt[i],x));
		}
		void Prev(int i,int x)
		{
			int l,r;
			Split(rt[i],x-1,l,r);
			printf("%d
",FindKth(l,s[l].size));
			Merge(rt[i],l,r);
		}
		void Next(int i,int x)
		{
			int l,r;
			Split(rt[i],x,l,r);
			printf("%d
",FindKth(r,1));
			Merge(rt[i],l,r);
		}
	private:
		int cnt,rt[MAXN];
		struct Node
		{
			int v,p,size,c[2];
			Node(int v=0,int p=0,int size=0):v(v),p(p),size(size)
			{
				c[0]=c[1]=0;
			}
		}s[MAXN*50];
		void Update(int i)
		{
			s[i].size=s[s[i].c[0]].size+s[s[i].c[1]].size+1;
		}
		int NewNode(int x)
		{
			s[++cnt]=Node(x,rand(),1);
			return cnt;
		}
		void Split(int i,int x,int &l,int &r)
		{
			if(!i)
			{
				l=r=0;
				return;
			}
			if(x<s[i].v)
			{
				r=++cnt;
				s[r]=s[i];
				Split(s[r].c[0],x,l,s[r].c[0]);
				Update(r);
			}
			else
			{
				l=++cnt;
				s[l]=s[i];
				Split(s[l].c[1],x,s[l].c[1],r);
				Update(l);
			}
		}
		void Merge(int &i,int l,int r)
		{
			if(!l || !r)
			{
				i=l|r;
				return;
			}
			i=++cnt;
			if(s[l].p>s[r].p)
			{
				i=r;
				Merge(s[r].c[0],l,s[r].c[0]);
			}
			else
			{
				i=l;
				Merge(s[l].c[1],s[l].c[1],r);
			}
			Update(i);
		}
		int FindKth(int i,int x)
		{
			int t;
			while(x^(t=s[s[i].c[0]].size+1))
				if(x>t)
					x-=t,i=s[i].c[1];
				else
					i=s[i].c[0];
			return s[i].v;
		}
}*T=new FHQ_Treap;
int main(int argc,char** argv)
{
	scanf("%d",&n);
	for(int i=1,j,opt,x;i<=n;++i)
	{
		scanf("%d %d %d",&j,&opt,&x);
		T->Copy(i,j);
		switch(opt)
		{
			case 1:
				T->Insert(i,x);
				break;
			case 2:
				T->Delete(i,x);
				break;
			case 3:
				T->Rank(i,x);
				break;
			case 4:
				T->Find(i,x);
				break;
			case 5:
				T->Prev(i,x);
				break;
			case 6:
				T->Next(i,x);
				break;
		}
	}
	delete T;
	return 0;
}

Thanks for reading.

原文地址:https://www.cnblogs.com/Capella/p/9053681.html