题意:给你一串数字,左右指针的位置,有五种操作,左右指针的左移右移,删除左指针右边的数,删除右指针左边的数,翻转两个指针之间的数。
Splay搞过去了。。T了几发是因为,删除的时候,可以把要删除的那个点转到根结点,删除根结点,合并两个子树,然后这样就T了,换了个姿势就过了。。C++扩栈不解释。。
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define LL(x) (ch[x][0])
#define RR(x) (ch[x][1])
#define MID(a,b) (a+((b-a)>>1))
#define Kt ( ch[ ch[Rt][1] ][0] )
const int N=1000005;
int n,m;
int a[N/2],cnt;
int posL,posR;
int ans[N];
struct SplayTree
{
int Rt,top;
int pre[N],sz[N],ch[N][2];
int key[N];
bool flip[N];
inline void Link(int x,int y,int f)
{
pre[x]=y; if(y!=0) ch[y][f]=x;
}
inline void Rotate(int x,int f)
{
int y=pre[x],z=pre[y];
PushDown(y); PushDown(x);
Link(x,z,RR(z)==y);
Link(ch[x][f],y,!f);
Link(y,x,f);
PushUp(y);
}
inline void Splay(int x,int goal)
{
while(pre[x]!=goal)
{
int y=pre[x],z=pre[y];
int cx=(LL(y)==x),cy=(LL(z)==y);
if(z==goal) Rotate(x,cx);
else
{
if(cx==cy) Rotate(y,cy);
else Rotate(x,cx);
Rotate(x,cy);
}
}
PushUp(x);
if(goal==0) Rt=x;
}
inline void Select(int K,int goal)
{
int x=Rt;
PushDown(x);
while(1)
{
if(sz[LL(x)]>=K) x=LL(x);
else if(sz[LL(x)]+1==K) break;
else K-=sz[LL(x)]+1,x=RR(x);
PushDown(x);
}
Splay(x,goal);
}
inline void Insert(int pos,int valu)
{
Select(pos,0);
Select(pos+1,Rt);
addNode(valu,Kt,RR(Rt));
PushUp(RR(Rt)); PushUp(Rt);
}
inline void Delete(int pos)
{
if(pos==1||pos==sz[Rt]) return;
Select(pos-1,0);
Select(pos+1,Rt);
LL(RR(Rt))=0;
PushUp(RR(Rt)); PushUp(Rt);
}
inline void iswap(int x)
{
if(x==0) return;
flip[x]^=1;
swap(LL(x),RR(x));
}
inline void Flip(int st,int ed)
{
Select(st-1,0);
Select(ed+1,Rt);
iswap(Kt);
}
inline void PushDown(int x)
{
if(flip[x])
{
iswap(LL(x)); iswap(RR(x));
flip[x]=0;
}
}
inline void PushUp(int x)
{
sz[x]=1+sz[LL(x)]+sz[RR(x)];
}
inline void addNode(int valu,int &x,int f)
{
x=++top;
pre[x]=f; LL(x)=RR(x)=0; sz[x]=1;
key[x]=valu; flip[x]=0;
}
void build(int lft,int rht,int &x,int fa)
{
if(lft>rht) return;
int mid=MID(lft,rht);
addNode(a[mid],x,fa);
build(lft,mid-1,LL(x),x);
build(mid+1,rht,RR(x),x);
PushUp(x);
}
void init()
{
Rt=top=0;
sz[0]=pre[0]=LL(0)=RR(0)=flip[0]=0;
addNode(0,Rt,0);
addNode(0,RR(Rt),Rt);
build(0,n-1,Kt,RR(Rt));
PushUp(RR(Rt)); PushUp(Rt);
}
void Debug() { printf("Rt:%d\n",Rt); Travel(Rt,0); }
void Travel(int x,bool flag)
{
if(x==0) return;
PushDown(x);
Travel(LL(x),flag);
if(flag==0) printf("node:%d,pre:%d,lSon:%d,rSon:%d,sz:%d,key:%d\n",x,pre[x],LL(x),RR(x),sz[x],key[x]);
if(cnt>=1&&cnt<sz[Rt]-1)
{
if(cnt==1) printf("%d",key[x]);
else printf(" %d",key[x]);
}
cnt++;
Travel(RR(x),flag);
}
}spt;
int main()
{
freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
scanf("%d%d",&posL,&posR);
posR+=2;
spt.init();
int valu;
char op1[100],op2[100];
scanf("%d",&m);
while(m--)
{
scanf("%s",op1);
int len=spt.sz[spt.Rt];
if(op1[0]=='M')
{
scanf("%s",op2);
if(op1[4]=='L')
{
if(op2[0]=='L') posL-=(posL>1);
else posR-=(posR>1);
}
else
{
if(op2[0]=='L') posL+=(posL<len);
else posR+=(posR<len);
}
}
else if(op1[0]=='I')
{
scanf("%s%d",op2,&valu);
if(op2[0]=='L') spt.Insert(posL,valu);
else spt.Insert(posR-1,valu);
posR++;
}
else if(op1[0]=='D')
{
scanf("%s",op2);
if(op2[0]=='L') spt.Delete(posL+1);
else spt.Delete(posR-1);
posR--;
}
else
{
spt.Flip(posL+1,posR-1);
}
}
cnt=0;
spt.Travel(spt.Rt,1);
puts("");
}
return 0;
}