1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4
5 const int MAXL = 2 * 1024 * 1024 + 100;
6 const int BLOCK_SIZE = 5000;
7 const int BLOCK_NUM = MAXL / BLOCK_SIZE * 2 + 100;
8 int indexPool[BLOCK_NUM];
9 int blockNum;
10 int nxt[BLOCK_NUM], curSize[BLOCK_NUM];
11 char data[BLOCK_NUM][BLOCK_SIZE];
12
13 void init(){
14 for(int i = 1; i < BLOCK_NUM; i++){
15 indexPool[i] = i;
16 }
17 blockNum = 1;
18 nxt[0] = -1;
19 curSize[0] = 0;
20 }
21 int getNewBlock(){
22 return indexPool[blockNum++];
23 }
24 void deleteBlock(int blockIndex){
25 indexPool[--blockNum] = blockIndex;
26 }
27 int getCurBlock(int &pos){
28 int blockIndex = 0;
29 while(blockIndex != -1 && pos > curSize[blockIndex]){
30 pos -= curSize[blockIndex];
31 blockIndex = nxt[blockIndex];
32 }
33 return blockIndex;
34 }
35 void addNewBlock(int curBlock, int newBlock, int num, char str[]){
36 if(newBlock != -1){
37 nxt[newBlock] = nxt[curBlock];
38 curSize[newBlock] = num;
39 memcpy(data[newBlock], str, num);
40 }
41 nxt[curBlock] = newBlock;
42 }
43
44 void split(int curBlock, int pos){
45 if(curBlock == -1 || pos == curSize[curBlock]) return ;
46 int newBlock = getNewBlock();
47 addNewBlock(curBlock, newBlock, curSize[curBlock] - pos, data[curBlock] + pos);
48 curSize[curBlock] = pos;
49 }
50
51 void merge(int curBlock, int nxtBlock){
52 memcpy(data[curBlock] + curSize[curBlock], data[nxtBlock], curSize[nxtBlock]);
53 curSize[curBlock] += curSize[nxtBlock];
54 nxt[curBlock] = nxt[nxtBlock];
55 deleteBlock(nxtBlock);
56 }
57 void maintainList(){
58 int curBlock = 0;
59 while(curBlock != -1){
60 int nxtBlock = nxt[curBlock];
61 while(nxtBlock != -1 && curSize[curBlock] + curSize[nxtBlock] <= BLOCK_SIZE){
62 merge(curBlock, nxtBlock);
63 nxtBlock = nxt[curBlock];
64 }
65 curBlock = nxt[curBlock];
66 }
67 }
68 void insert(int pos, int num, char str[]){
69 int curBlock = getCurBlock(pos);
70 split(curBlock, pos);
71 int curNum = 0;
72 while(curNum + BLOCK_SIZE <= num){
73 int newBlock = getNewBlock();
74 addNewBlock(curBlock, newBlock, BLOCK_SIZE, str + curNum);
75 curBlock = newBlock;
76 curNum += BLOCK_SIZE;
77 }
78 if(num - curNum){
79 int newBlock = getNewBlock();
80 addNewBlock(curBlock, newBlock, num - curNum, str + curNum);
81 }
82 maintainList();
83 }
84 void erase(int pos, int num){
85 int curBlock = getCurBlock(pos);
86 split(curBlock, pos);
87 int nxtBlock = nxt[curBlock];
88 while(nxtBlock != -1 && num > curSize[nxtBlock]){
89 num -= curSize[nxtBlock];
90 nxtBlock = nxt[nxtBlock];
91 }
92 split(nxtBlock, num);
93 nxtBlock = nxt[nxtBlock];
94 for(int p = nxt[curBlock]; p != nxtBlock; p = nxt[curBlock]){
95 nxt[curBlock] = nxt[p];
96 deleteBlock(p);
97 }
98 maintainList();
99 }
100
101 void getData(int pos, int num, char str[]){
102 int curBlock = getCurBlock(pos);
103 int index = curSize[curBlock] - pos;
104 if(num < index) index = num;
105 memcpy(str, data[curBlock] + pos, index);
106 int tmpBlock = nxt[curBlock];
107 while(tmpBlock != -1 && index + curSize[tmpBlock] <= num){
108 memcpy(str + index, data[tmpBlock], curSize[tmpBlock]);
109 index += curSize[tmpBlock];
110 tmpBlock = nxt[tmpBlock];
111 }
112 if(num - index && tmpBlock != -1){
113 memcpy(str + index, data[tmpBlock], num - index);
114 }
115 str[num] = ‘\0‘;
116 }
117
118 char str[MAXL], cd[20];
119 int main(){
120 init();
121 int curPos = 0;
122 int opNum, num;
123 char ch;
124 scanf("%d", &opNum);
125 while(opNum--){
126 scanf("%s", cd);
127 if(cd[0] == ‘M‘){
128 scanf("%d", &curPos);
129 }else if(cd[0] == ‘I‘){
130 scanf("%d", &num);
131 for(int i = 0; i < num; i++){
132 scanf("%c", &ch);
133 str[i] = ch;
134 if(ch < 32 || ch > 126) --i;
135 }
136 insert(curPos, num, str);
137 }else if(cd[0] == ‘D‘){
138 scanf("%d", &num);
139 erase(curPos, num);
140 }else if(cd[0] == ‘G‘){
141 scanf("%d", &num);
142 getData(curPos, num, str);
143 printf("%s\n", str);
144 }else if(cd[0] == ‘P‘){
145 --curPos;
146 }else if(cd[0] == ‘N‘){
147 ++curPos;
148 }
149 }
150 return 0;
151 }