对输入数据我们有如下假定:? MOVE操作不超过50 000个,INSERT、DELETE和ROTATE操作作的总个数不超过6 000,GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。? 所有INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。? DELETE操作、ROTATE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。? 输入文件没有错误。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n,m,root,now,tot;
struct node
{
int ch[2],fa,v,siz,tag;
}s[1024*2048+10];
char str[1024*2048+10];
void pushup(int x)
{
s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
}
void pushdown(int x)
{
if(s[x].tag)
{
swap(s[x].ch[0],s[x].ch[1]);
s[s[x].ch[0]].tag^=1,s[s[x].ch[1]].tag^=1;
s[x].tag=0;
}
}
int find(int y,int x)
{
if(!x) return 0;
pushdown(x);
if(s[s[x].ch[0]].siz>=y) return find(y,s[x].ch[0]);
if(s[s[x].ch[0]].siz+1==y) return x;
return find(y-s[s[x].ch[0]].siz-1,s[x].ch[1]);
}
void rotate(int x,int &k)
{
int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
if(z) s[z].ch[(y==s[z].ch[1])]=x;
if(y==k) k=x;
s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];
if(s[x].ch[d^1]) s[s[x].ch[d^1]].fa=y;
s[x].ch[d^1]=y;
pushup(y),pushup(x);
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=s[x].fa,z=s[y].fa;
if(y!=k)
{
if((x==s[y].ch[0])^(y==s[z].ch[0])) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void build(int l,int r,int last,int d)
{
if(l>r) return ;
int tmp=++tot,mid=l+r>>1;
s[tmp].fa=last;
s[last].ch[d]=tmp;
s[tmp].v=str[mid]-32;
build(l,mid-1,tmp,0),build(mid+1,r,tmp,1);
pushup(tmp);
}
int main()
{
scanf("%d",&n);
s[1].ch[1]=2,s[1].siz=2,s[2].siz=1,s[2].fa=1,now=root=1,tot=2;
for(int i=1;i<=n;i++)
{
scanf("%s",str);
switch(str[0])
{
case ‘M‘:
{
scanf("%d",&now),now++;
break;
}
case ‘I‘:
{
scanf("%d%*c",&m);
gets(str);
splay(find(now,root),root),splay(find(now+1,root),s[root].ch[1]);
build(0,m-1,s[root].ch[1],0);
pushup(s[root].ch[1]),pushup(root);
break;
}
case ‘D‘:
{
scanf("%d",&m);
splay(find(now,root),root),splay(find(now+m+1,root),s[root].ch[1]);
s[s[root].ch[1]].ch[0]=0;
pushup(s[root].ch[1]),pushup(root);
break;
}
case ‘R‘:
{
scanf("%d",&m);
splay(find(now,root),root),splay(find(now+m+1,root),s[root].ch[1]);
s[s[s[root].ch[1]].ch[0]].tag^=1;
break;
}
case ‘G‘:
{
printf("%c\n",s[find(now+1,root)].v+32);
break;
}
case ‘P‘:
{
now--;
break;
}
case ‘N‘:
{
now++;
break;
}
}
}
return 0;
}