Editor
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 }