hdu3487:Play with Chain (splay)

  • Post author:
  • Post category:其他

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3487

题目大意:要你维护一个序列,支持两种操作:cut a b c,把原序列的[a,b]这段剪切下来,接到新序列的第c位后面;flip a b,翻转[a,b]。

分析:没什么好说的,splay裸题一道,一次cut操作意味着一次分离与一次合并,flip的话懒惰标记就好了。

CODE:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=300100;

struct Tnode
{
	int val,Size;
	bool flip;
	Tnode *son[2],*fa;
	int Lsize() { return son[0]?son[0]->Size:0; }
	void Get_size() { Size=Lsize()+(son[1]?son[1]->Size:0)+1; }
	int Get_d() { return fa->son[1]==this; }
	void Connect(Tnode *P,int d) { (son[d]=P)->fa=this; }
	void Push_down()
	{
		if (flip)
		{
			swap(son[0],son[1]);
			if (son[0]) son[0]->flip^=1;
			if (son[1]) son[1]->flip^=1;
			flip=0;
		}
	}
} tree[maxn];
Tnode *Root;
int cur;

char op[15];
int n,m;

Tnode *Build(Tnode *F,int L,int R)
{
	if (L>R) return NULL;
	Tnode *P=&tree[++cur];
	int mid=(L+R)>>1;
	P->val=mid;
	P->fa=F;
	P->flip=false;
	P->son[0]=Build(P,L,mid-1);
	P->son[1]=Build(P,mid+1,R);
	P->Get_size();
	return P;
}

void Zig(Tnode *P,Tnode *&tag)
{
	Tnode *F=P->fa;
	int d=P->Get_d();
	if (P->son[!d]) F->Connect(P->son[!d],d);
	else F->son[d]=NULL;
	if (F!=tag) F->fa->Connect(P,F->Get_d());
	else
	{
		P->fa=F->fa;
		tag=P;
	}
	P->Connect(F,!d);
	F->Get_size();
}

void Splay(Tnode *P,Tnode *&tag)
{
	Tnode *F;
	while (P!=tag)
	{
		F=P->fa;
		if (F!=tag) ( P->Get_d()^F->Get_d() )? Zig(P,tag):Zig(F,tag);
		Zig(P,tag);
	}
	P->Get_size();
}

void Work(Tnode *P,int rank,Tnode *&tag)
{
	P->Push_down();
	int ls=P->Lsize()+1;
	if (rank<ls) Work(P->son[0],rank,tag);
	if (rank==ls) Splay(P,tag);
	if (rank>ls) Work(P->son[1],rank-ls,tag);
}

void Print(Tnode *P)
{
	if (!P) return;
	P->Push_down();
	Print(P->son[0]);
	if ( P->val && P->val!=n+1 )
	{
		printf("%d",P->val);
		if (P!=Root) printf(" ");
	}
	Print(P->son[1]);
}

int main()
{
	freopen("c.in","r",stdin);
	freopen("c.out","w",stdout);
	
	scanf("%d%d",&n,&m);
	while ( n>0 && m>=0 )
	{
		cur=-1;
		Root=Build(NULL,0,n+1);
		
		for (int i=1; i<=m; i++)
		{
			scanf("%s",&op);
			if (op[0]=='C')
			{
				int a,b,c;
				scanf("%d%d%d",&a,&b,&c);
				
				Work(Root,a,Root);
				Work(Root,b+2,Root->son[1]);
				Tnode *tag=Root->son[1]->son[0];
				Root->son[1]->son[0]=NULL;
				Root->son[1]->Get_size();
				Root->Get_size();
				
				Work(Root,c+1,Root);
				Work(Root,c+2,Root->son[1]);
				Root->son[1]->Connect(tag,0);
				Root->son[1]->Get_size();
				Root->Get_size();
			}
			
			if (op[0]=='F')
			{
				int L,R;
				scanf("%d%d",&L,&R);
				Work(Root,L,Root);
				Work(Root,R+2,Root->son[1]);
				Root->son[1]->son[0]->flip^=1;
			}
		}
		
		Work(Root,Root->Size-1,Root);
		Print(Root);
		printf("\n");
		scanf("%d%d",&n,&m);
	}
	
	return 0;
}


版权声明:本文为KsCla原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。