题目传送门: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 版权协议,转载请附上原文出处链接和本声明。