「模板」 树套树

「模板」 树套树

<题目链接>


线段树套 SBT。

有生以来写过的最长代码。

#include <algorithm>
#include <climits>
#include <cstdio>
using std::max;
using std::min;
const int MAXN=50010;
int n,m;
class SegmentTree
{
	private:
		int a[MAXN];
		class SBT
		{
			private:
				struct Node
				{
					int v,size;
					Node *c[2];
					Node(int v):v(v),size(1)
					{
						c[0]=c[1]=nullptr;
					}
					~Node(void)
					{
						if(c[0]!=nullptr)
							delete c[0];
						if(c[1]!=nullptr)
							delete c[1];
					}
					int Size(bool p)
					{
						return c[p]!=nullptr ? c[p]->size : 0;
					}
					int SubSize(bool p,bool q)
					{
						return c[p]!=nullptr ? c[p]->Size(q) : 0;
					}
					void Update(void)
					{
						size=Size(0)+Size(1)+1;
					}
				}*rt;
				void Rotate(Node* &i,bool p)
				{
					Node *t=i->c[!p];
					i->c[!p]=t->c[p];
					t->c[p]=i;
					i->Update();
					(i=t)->Update();
				}
				void Maintain(Node* &i,bool p)
				{
					int t=i->Size(!p);
					if(t<i->SubSize(p,p))
						Rotate(i,!p);
					else if(t<i->SubSize(p,!p))
					{
						Rotate(i->c[p],p);
						Rotate(i,!p);
					}
					else
						return;
					Maintain(i->c[0],0);
					Maintain(i->c[1],1);
					Maintain(i,0);
					Maintain(i,1);
				}
				void Insert(Node* &i,int x)
				{
					if(i==nullptr)
					{
						i=new Node(x);
						return;
					}
					bool p=x>i->v;
					++i->size;
					Insert(i->c[p],x);
					Maintain(i,p);
				}
				void Delete(Node* &i,int x)
				{
					if(i==nullptr)
						return;
					if(x==i->v)
						if(i->c[1]==nullptr)
						{
							Node *t=i;
							i=i->c[0];
							t->c[0]=t->c[1]=nullptr;
							delete t;
							return;
						}
						else
						{
							Node *t=i->c[1];
							while(t->c[0]!=nullptr)
								t=t->c[0];
							i->v=t->v;
							Delete(i->c[1],t->v);
						}
					else
						Delete(i->c[x>i->v],x);
					i->Update();
				}
			public:
				SBT(int* a,int l,int r):rt(nullptr)
				{
					for(int i=l;i<=r;++i)
						Insert(a[i]);
				}
				~SBT(void)
				{
					delete rt;
				}
				void Insert(int x)
				{
					Insert(rt,x);
				}
				void Delete(int x)
				{
					Delete(rt,x);
				}
				int Rank(int x)
				{
					int ans=1;
					Node *i=rt;
					while(i!=nullptr)
						if(x>i->v)
						{
							ans+=i->Size(0)+1;
							i=i->c[1];
						}
						else
							i=i->c[0];
					return ans-1;
				}
				int Prev(int x)
				{
					int ans=-INT_MAX;
					Node *i=rt;
					while(i!=nullptr)
						if(x>i->v)
						{
							ans=max(ans,i->v);
							i=i->c[1];
						}
						else
							i=i->c[0];
					return ans;
				}
				int Next(int x)
				{
					int ans=INT_MAX;
					Node *i=rt;
					while(i!=nullptr)
						if(x<i->v)
						{
							ans=min(ans,i->v);
							i=i->c[0];
						}
						else
							i=i->c[1];
					return ans;
				}
		};
		struct Node
		{
			SBT *T;
			int l,r;
			Node *c[2];
			Node(SBT* T,int l,int r):T(T),l(l),r(r)
			{
				c[0]=c[1]=nullptr;
			}
			~Node(void)
			{
				delete T;
				if(c[0]!=nullptr)
					delete c[0];
				if(c[1]!=nullptr)
					delete c[1];
			}
		}*rt;
		void Build(Node* &i,int l,int r)
		{
			i=new Node(new SBT(a,l,r),l,r);
			if(l^r)
			{
				int mid=l+r>>1;
				Build(i->c[0],l,mid);
				Build(i->c[1],mid+1,r);
			}
		}
		int Rank(Node* i,int l,int r,int k)
		{
			if(l==i->l && r==i->r)
				return i->T->Rank(k);
			int mid=i->l+i->r>>1;
			if(r<=mid)
				return Rank(i->c[0],l,r,k);
			else if(l>mid)
				return Rank(i->c[1],l,r,k);
			else
				return Rank(i->c[0],l,mid,k)+Rank(i->c[1],mid+1,r,k);
		}
		void Modify(Node* i,int pos,int k)
		{
			i->T->Delete(a[pos]);
			i->T->Insert(k);
			if(pos==i->l && pos==i->r)
				return;
			int mid=i->l+i->r>>1;
			if(pos>mid)
				Modify(i->c[1],pos,k);
			else
				Modify(i->c[0],pos,k);
		}
		int Prev(Node* i,int l,int r,int k)
		{
			if(l==i->l && r==i->r)
				return i->T->Prev(k);
			int mid=i->l+i->r>>1;
			if(r<=mid)
				return Prev(i->c[0],l,r,k);
			else if(l>mid)
				return Prev(i->c[1],l,r,k);
			else
				return max(Prev(i->c[0],l,mid,k),Prev(i->c[1],mid+1,r,k));
		}
		int Next(Node* i,int l,int r,int k)
		{
			if(l==i->l && r==i->r)
				return i->T->Next(k);
			int mid=i->l+i->r>>1;
			if(r<=mid)
				return Next(i->c[0],l,r,k);
			else if(l>mid)
				return Next(i->c[1],l,r,k);
			else
				return min(Next(i->c[0],l,mid,k),Next(i->c[1],mid+1,r,k));
		}
	public:
		SegmentTree(int n):rt(nullptr)
		{
			for(int i=1;i<=n;++i)
				scanf("%d",&a[i]);
			Build(rt,1,n);
		}
		~SegmentTree(void)
		{
			delete rt;
		}
		void Rank(void)
		{
			int l,r,k;
			scanf("%d %d %d",&l,&r,&k);
			printf("%d
",Rank(rt,l,r,k)+1);
		}
		void Find(void)
		{
			int l,r,k,left=0,right=int(1e8),mid;
			scanf("%d %d %d",&l,&r,&k);
			while(left<right)
			{
				int mid=left+right>>1;
				if(k>Rank(rt,l,r,mid))
					left=mid+1;
				else
					right=mid;
			}
			printf("%d
",left-1);
		}
		void Modify(void)
		{
			int pos,k;
			scanf("%d %d",&pos,&k);
			Modify(rt,pos,k);
			a[pos]=k;
		}
		void Prev(void)
		{
			int l,r,k;
			scanf("%d %d %d",&l,&r,&k);
			printf("%d
",Prev(rt,l,r,k));
		}
		void Next(void)
		{
			int l,r,k;
			scanf("%d %d %d",&l,&r,&k);
			printf("%d
",Next(rt,l,r,k));
		}
};
int main(int argc,char** argv)
{
	scanf("%d %d",&n,&m);
	static SegmentTree *T=new SegmentTree(n);
	for(int i=1,opt;i<=m;++i)
	{
		scanf("%d",&opt);
		switch(opt)
		{
			case 1:
				T->Rank();
				break;
			case 2:
				T->Find();
				break;
			case 3:
				T->Modify();
				break;
			case 4:
				T->Prev();
				break;
			case 5:
				T->Next();
				break;
		}
	}
	delete T;
	return 0;
}

谢谢阅读。

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