1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=2e3+10;
4 struct node{
5 int ne,siz;//每一块数组的后继以及大小
6 char a[maxn<<1];
7 }b[maxn<<2];
8 int n;
9 int bg[maxn<<2],cnt,cp;//属于哪个块、第几个块以及题目光标位置
10 int addi()
11 {
12 cnt++;
13 return bg[cnt];
14 }
15 void dele(int x)
16 {
17 bg[cnt]=x;
18 cnt--;
19 }
20 void init()
21 {
22 for(int i=1;i<(maxn<<2);++i) bg[i]=i;
23 cnt=1;
24 b[1].siz=0,b[1].ne=-1;
25 }
26 void add(int x,int y,int len,char c[])//在第x块后添加一个编号为y的块,长度为len
27 {
28 if(y!=-1)
29 {
30 b[y].ne=b[x].ne,b[y].siz=len;
31 memcpy(b[y].a,c,len);
32 }
33 b[x].ne=y;
34 }
35 void merge(int x,int y)//将第x块和第y块合并
36 {
37 memcpy(b[x].a+b[x].siz,b[y].a,b[y].siz);
38 b[x].siz+=b[y].siz,b[x].ne=b[y].ne;
39 dele(y);
40 }
41 void split(int k,int pos)//将第k块从pos处分割
42 {
43 if(k==-1||pos==b[k].siz) return ;
44 add(k,addi(),b[k].siz-pos,b[k].a+pos);
45 b[k].siz=pos;
46 }
47 int pos(int &x)//寻找当前光标所在的块和块内位置
48 {
49 int now=1;
50 while(now!=-1&&x>b[now].siz) x-=b[now].siz,now=b[now].ne;
51 return now;
52 }
53 void insert(int p,int len,char c[])//在p位置之后插入长度为len的字符串
54 {
55 int now=pos(p);
56 split(now,p);
57 //cout<<now<<" "<<b[now].ne<<" "<<b[now].siz<<endl;
58 int tot=0,nb,st=now;
59 while(tot+maxn<=len)//维护块状链表平衡
60 {
61 nb=addi();
62 add(now,nb,maxn,c+tot);
63 tot+=maxn;
64 now=nb;
65 }
66 if(len-tot)
67 nb=addi(),add(now,nb,len-tot,c+tot);
68 if(b[now].siz+b[nb].siz<maxn&&nb!=-1)//不用对整个链表进行判断,部分maintain
69 merge(now,nb),nb=b[now].ne;
70 if(b[st].siz+b[b[st].ne].siz<maxn&&b[st].ne!=-1)//同理
71 merge(st,b[st].ne);
72 //cout<<"insert "<<now<<" "<<b[now].siz<<" "<<b[now].ne<<endl;
73 }
74 void erase(int p,int len)//在p位置之后删除长度为len的字符串
75 {
76 int now=pos(p);
77 split(now,p);
78 int ne=b[now].ne;
79 //cout<<"pp "<<now<<" "<<cnt<<" "<<b[now].ne<<endl;
80 while(ne!=-1&&len>b[ne].siz)
81 len-=b[ne].siz,ne=b[ne].ne;
82 split(ne,len);
83 ne=b[ne].ne;
84 for(int i=b[now].ne;i!=ne;i=b[now].ne)
85 b[now].ne=b[i].ne,dele(i);
86 //cout<<"pp2 "<<now<<" "<<cnt<<" "<<b[now].ne<<" "<<ne<<endl;
87 while(b[now].siz+b[ne].siz<maxn&&ne!=-1)//不用对整个链表进行判断,部分maintain
88 merge(now,ne),ne=b[now].ne;
89 }
90 char ss[20000000],s[1000];
91 void get(int p,int len)//输出p位置后长度为len的字符串
92 {
93 int k=pos(p);
94 int tot=b[k].siz-p;
95 if(len<tot) tot=len;
96 memcpy(ss,b[k].a+p,tot);
97 int now=b[k].ne;
98 while(now!=-1&&len>=tot+b[now].siz)
99 {
100 memcpy(ss+tot,b[now].a,b[now].siz);
101 tot+=b[now].siz,now=b[now].ne;
102 }
103 if(len-tot>0&&now!=-1)
104 memcpy(ss+tot,b[now].a,len-tot);
105 //cout<<"get "<<now<<endl;
106 for(int i=0;i<len;++i) cout<<ss[i];
107 cout<<endl;
108 }
109 int main()
110 {
111 init();
112 scanf("%d",&n);
113 while(n--)
114 {
115 int len;
116 scanf("%s",s);
117 if(s[0]=='M')
118 {
119 scanf("%d",&cp);
120 }
121 else if(s[0]=='I')
122 {
123 scanf("%d",&len);getchar();
124 for(int i=0;i<len;++i)
125 {
126 ss[i]=getchar();
127 if(ss[i]<32||ss[i]>126) --i;
128 }
129 insert(cp,len,ss);
130 }
131 else if(s[0]=='D')
132 {
133 scanf("%d",&len);
134 erase(cp,len);
135 }
136 else if(s[0]=='G')
137 {
138 scanf("%d",&len);
139 get(cp,len);
140 }
141 else if(s[0]=='P')
142 {
143 cp--;
144 }
145 else if(s[0]=='N')
146 {
147 cp++;
148 }
149 // cout<<"zzzzz "<<n<<" pos "<<cp<<" "<<s[0]<<endl;
150 // get(cp,2);
151 }
152 return 0;
153 }