hdu3487:Play with Chain (splay)

来源:互联网 发布:mysql 断电 无法启动 编辑:程序博客网 时间:2024/05/29 19:19

题目传送门: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;}

1 0
原创粉丝点击