Description
Input
输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。其中: 为了使输入文件便于阅读,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秒。
Output
输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。
Sample Input
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
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
Sample Output
.\/.
abcde^_^f.\/.ghijklmno
abcde^_^f.\/.ghijklmno
Solution
这道题是Splay维护区间的模板题,技巧是在两端各插入一个没用的字符,代码会短很多,插入删除的时候不用特判端点的情况。注意输入的时候不要写挂。
代码:
#include<cstdio>
#include<cstring>
#include<cstring>
#include<algorithm>
using namespace std;
#define lc T[x].ch[0]
#define rc T[x].ch[1]
#define getson(x) (x==T[T[x].fa].ch[1])
inline int read(){
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
const int maxn=(1<<21)+10;
struct node{
int fa,ch[2],size;
char s;
}T[maxn];
int n,num=0,root,now;
char ch[maxn];
void create(char c){
T[++num].s=c;
T[num].fa=T[num].ch[0]=T[num].ch[1]=0;
T[num].size=1;
}
void update(int x){
T[x].size=1;
if(lc)T[x].size+=T[lc].size;
if(rc)T[x].size+=T[rc].size;
}
int build(int l,int r,int fa){
if(l>r)return 0;
int mid=(l+r)>>1;
create(ch[mid]);
int temp=num;
T[temp].fa=fa;
T[temp].ch[0]=build(l,mid-1,temp);
T[temp].ch[1]=build(mid+1,r,temp);
update(temp);
return temp;
}
void rotate(int p){
if(!T[p].fa)return;
int k=getson(p),fa=T[p].fa;
int fafa=T[fa].fa;
T[fa].ch[k]=T[p].ch[k^1];
if(T[p].ch[k^1])T[T[p].ch[k^1]].fa=fa;
T[p].ch[k^1]=fa;
T[fa].fa=p;
T[p].fa=fafa;
if(fafa)T[fafa].ch[fa==T[fafa].ch[1]]=p;
update(fa);update(p);
}
void Splay(int u,int f){
for(int fa;(fa=T[u].fa)!=f;rotate(u)){
if(T[fa].fa!=f){
rotate((getson(u)==getson(fa))?fa:u);
}
}
if(!f)root=u;
}
int Rank(int x){
int p=root;
while(1){
if(T[p].ch[0]&&x<=T[T[p].ch[0]].size)p=T[p].ch[0];
else{
int temp=T[T[p].ch[0]].size+1;
if(x==temp)return p;
x-=temp;
p=T[p].ch[1];
}
}
}
void Insert(int nrt){
Splay(Rank(now),0);Splay(Rank(now+1),root);
T[T[root].ch[1]].ch[0]=nrt;
T[nrt].fa=T[root].ch[1];
update(T[root].ch[1]);update(root);
}
void Delete(int x){
Splay(Rank(now),0);Splay(Rank(now+x+1),root);
T[T[root].ch[1]].ch[0]=0;
update(T[root].ch[1]);update(root);
}
void print(int x){
if(!x)return;
print(lc);
printf("%c",T[x].s);
print(rc);
}
void Display(int x){
Splay(Rank(now),0);Splay(Rank(now+x+1),root);
print(T[T[root].ch[1]].ch[0]);putchar(10);
}
void Init(){
n=read();now=1;
ch[0]=ch[1]='@';
root=build(0,1,0);
}
void Work(){
while(n--){
char opt[10],temp;
int x;
scanf("%s",opt);
if(opt[0]=='I'){
x=read();
for(int i=0;i<x;){
temp=getchar();
if(temp=='\n')continue;
ch[i++]=temp;
}
Insert(build(0,x-1,0));
}
else if(opt[0]=='D')Delete(read());
else if(opt[0]=='M')now=read()+1;
else if(opt[0]=='P')now--;
else if(opt[0]=='N')now++;
else Display(read());
}
}
int main(){
Init();
Work();
return 0;
}