[Luogu 2596] ZJOI2006 书架

[Luogu 2596] ZJOI2006 书架

<题目链接>


第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦!

省选试机写它,紧张过度失败了。

省选 Day 1 考场写它,写挂了。

省选 Day 1 当晚认真复习它,结果 Day 2 并不考。

于是省选后用指针写出来了,开心qwq。

这个题嘛,记录一下每个点对应的指针,顺便维护一下父节点,每次需要的时候,就可以一路向上找到这个点的位置。

就这么简单的呀qwq

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <stack>
using std::stack;
const int MAXN=80010;
int n,m,pos[MAXN];
class FHQ_Treap
{
	public:
		FHQ_Treap(void)
		{
			srand(19260817);
			rt=nullptr;
		}
		~FHQ_Treap(void)
		{
			delete rt;
		}
		void Init(void)
		{
			Build(rt);
		}
		void Top(void)
		{
			int x;
			Node *l,*r,*t;
			scanf("%d",&x);
			x=Rank(pos[x]);
			Split(rt,x-1,l,r),Split(r,1,t,r),Merge(l,t,l),Merge(rt,l,r);
		}
		void Bottom(void)
		{
			int x;
			Node *l,*r,*t;
			scanf("%d",&x);
			x=Rank(pos[x]);
			Split(rt,x-1,l,r),Split(r,1,t,r),Merge(r,r,t),Merge(rt,l,r);
		}
		void Insert(void)
		{
			int x,k;
			scanf("%d %d",&x,&k);
			if(!k)
				return;
			Node *l,*r,*p,*q;
			x=Rank(pos[x]);
			if(k==-1)
				Split(rt,x-2,l,r);
			else
				Split(rt,x-1,l,r);
			Split(r,1,p,r),Split(r,1,q,r),Merge(l,l,q),Merge(r,p,r),Merge(rt,l,r);
		}
		void Ask(void)
		{
			int x;
			scanf("%d",&x);
			printf("%d\n",Rank(pos[x])-1);
		}
		void Query(void)
		{
			int x;
			Node *l,*r,*t;
			scanf("%d",&x);
			Split(rt,x-1,l,r),Split(r,1,t,r);
			printf("%d\n",t->v);
			Merge(l,l,t),Merge(rt,l,r);
		}
	private:
		struct Node
		{
			int v,p,num,size;
			Node *ft,*c[2];
			Node(int v=0,int p=0,int num=0,int size=0):v(v),p(p),num(num),size(size)
			{
				ft=c[0]=c[1]=nullptr;
			}
			~Node(void)
			{
				if(c[0]!=nullptr)
					delete c[0];
				if(c[1]!=nullptr)
					delete c[1];
			}
		}*rt,*pos[MAXN];
		void Update(Node *i)
		{
			i->size=1,pos[i->v]=i;
			if(i->c[0]!=nullptr)
			{
				i->size+=i->c[0]->size;
				i->c[0]->ft=i;
			}
			if(i->c[1]!=nullptr)
			{
				i->size+=i->c[1]->size;
				i->c[1]->ft=i;
			}
		}
		void Build(Node *&k)
		{
			stack<Node *> st;
			for(int i=1,t;i<=n;++i)
			{
				scanf("%d",&t);
				Node *x=new Node(t,rand(),i,1);
				pos[t]=x,k=nullptr;
				while(!st.empty() && x->p>st.top()->p)
					Update(k=st.top()),st.pop();
				if(!st.empty())
					st.top()->c[1]=x;
				x->c[0]=k,st.push(x);
			}
			while(!st.empty())
				Update(k=st.top()),st.pop();
		}
		void Split(Node *i,int x,Node *&l,Node *&r)
		{
			if(i==nullptr)
			{
				l=r=nullptr;
				return;
			}
			int t=(i->c[0]!=nullptr ? i->c[0]->size : 0)+1;
			if(x<t)
				Split((r=i)->c[0],x,l,i->c[0]);
			else
				Split((l=i)->c[1],x-t,i->c[1],r);
			Update(i);
		}
		void Merge(Node *&i,Node *l,Node *r)
		{
			if(l==nullptr || r==nullptr)
			{
				i=l!=nullptr ? l : r;
				return;
			}
			if(l->p>r->p)
				Merge((i=l)->c[1],l->c[1],r);
			else
				Merge((i=r)->c[0],l,r->c[0]);
			Update(i);
		}
		int Rank(Node *i)
		{
			int ans=(i->c[0]!=nullptr ? i->c[0]->size : 0)+1;
			while(i->ft!=nullptr)
			{
				if(i==i->ft->c[1])
					ans+=(i->ft->c[0]!=nullptr ? i->ft->c[0]->size : 0)+1;
				i=i->ft;
			}
			return ans;
		}
}*T=new FHQ_Treap;
int main(int argc,char *argv[])
{
	scanf("%d %d",&n,&m);
	T->Init();
	for(int i=1;i<=m;++i)
	{
		char str[10];
		scanf("\n%s",str);
		switch(str[0])
		{
			case 'T':
				T->Top();
				break;
			case 'B':
				T->Bottom();
				break;
			case 'I':
				T->Insert();
				break;
			case 'A':
				T->Ask();
				break;
			case 'Q':
				T->Query();
				break;
		}
	}
	delete T;
	return 0;
}

谢谢阅读。

posted @ 2018-05-03 20:46  Capella  阅读(138)  评论(0编辑  收藏  举报

谢谢光临