输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。
输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。
15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22
.\/.
abcde^_^f.\/.ghijklmno
为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例)。 除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。 这里我们有如下假定: MOVE操作不超过50000个,INSERT和DELETE操作的总个数不超过4000,PREV和NEXT操作的总个数不超过200000。 所有INSERT插入的字符数之和不超过2M(1M=1024*1024),正确的输出文件长度不超过3M字节。 DELETE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作必然不会试图把光标移动到非法位置。 输入文件没有错误。 对C++选手的提示:经测试,最大的测试数据使用fstream进行输入有可能会比使用stdio慢约1秒。
普通的序列splay…
不过要加一个变量pos记录光标的位置
其它没什么好说的了..
记得空间开大一点…
#include
#include
#include
#include
using namespace std;
#define maxn 2200233
char s[23];
struct splay{
int ch[2],fa,size;
char v;
}t[maxn];
int root,size=2;
inline void update(int k){t[k].size=t[t[k].ch[1]].size+t[t[k].ch[0]].size+1;}
inline int in()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
return x;
}
void rotate(int x,int &k,int d)
{
int y,z;
y=t[x].fa;z=t[y].fa;
if(y==k)k=x;
else {if(t[z].ch[0]==y)t[z].ch[0]=x;else t[z].ch[1]=x;}
t[x].fa=z,t[y].fa=x,t[t[x].ch[d]].fa=y;
t[y].ch[d^1]=t[x].ch[d],t[x].ch[d]=y;
update(y),update(x);
}
void splay(int x,int &k)
{
int y,z;
while(x!=k)
{
y=t[x].fa,z=t[y].fa;
if(y!=k)
{
if(t[y].ch[0]==x&&t[z].ch[0]==y)rotate(y,k,1);
else if(t[y].ch[1]==x&&t[z].ch[1]==y)rotate(y,k,0);
else if(t[y].ch[0]==x&&t[z].ch[1]==y)rotate(x,k,1);
else if(t[y].ch[1]==x&&t[z].ch[0]==y)rotate(x,k,0);
}
if(t[t[x].fa].ch[0]==x)rotate(x,k,1);
else rotate(x,k,0);
}
}
int find(int k,int x)
{
if(t[t[k].ch[0]].size>=x)return find(t[k].ch[0],x);
else if(t[t[k].ch[0]].size+1return find(t[k].ch[1],x-1-t[t[k].ch[0]].size);
else return k;
}
void print(int rt)
{
if(t[rt].ch[0])print(t[rt].ch[0]);
printf("%c",t[rt].v);
if(t[rt].ch[1])print(t[rt].ch[1]);
}
int main()
{
freopen("1507.in","r",stdin);
int n,pos=1;
scanf("%d",&n);
t[1].ch[1]=2;t[2].fa=1;t[1].size=2,t[2].size=1;root=1;
for(int i=1;i<=n;i++)
{
int x,tot,now,ans1,ans2;
char ch;
scanf("%s",s);
if(s[0]=='I')
{
ans1=find(root,pos);
ans2=find(root,pos+1);
splay(ans1,root);
splay(ans2,t[root].ch[1]);
x=in();
tot=0;now=ans2;
while(tot!=x)
{
ch=getchar();
if(ch!='\n')
{
size++;
t[size].size=x-tot;t[size].fa=now;t[size].v=ch;
if(now==ans2)t[now].ch[0]=size;
else t[now].ch[1]=size;
now=size;
tot++;
}
}
update(ans2);update(ans1);
}
else if(s[0]=='M')
{
pos=in()+1;
}
else if(s[0]=='D')
{
x=in();
ans1=find(root,pos);
ans2=find(root,pos+x+1);
splay(ans1,root);
splay(ans2,t[root].ch[1]);
t[ans2].size-=x;t[ans2].ch[0]=0;
update(ans1);
}
else if(s[0]=='G')
{
x=in();
ans1=find(root,pos);
ans2=find(root,pos+x+1);
splay(ans1,root);
splay(ans2,t[root].ch[1]);
print(t[ans2].ch[0]);
printf("\n");
}
else if(s[0]=='P')
{
pos--;
}
else if(s[0]=='N')
{
pos++;
}
}
}