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 16
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
HINT
splay区间操作的裸题,就当是练习模板吧!
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 int t,a,p = 1; 7 char cmd[20],s[1024*1024+10]; 8 class Splay 9 { 10 private: 11 struct Node 12 { 13 char ch;int size,cnt;Node *c[2],*fa; 14 Node (char _ch,Node *_fa) 15 { 16 ch = _ch; fa = _fa; 17 cnt = 1; c[0] = c[1] = NULL; 18 } 19 int lsz(){return c[0]?c[0]->size:0;} 20 int rsz(){return c[1]?c[1]->size:0;} 21 }; 22 Node *root; 23 inline void upd(Node *tag) 24 { 25 if (!tag) return; 26 tag->size = tag->cnt+tag->lsz()+tag->rsz(); 27 } 28 inline void zig(Node *tag,int d) 29 { 30 Node *f = tag -> fa; 31 int anti = d^1; 32 f -> c[d] = tag->c[anti]; 33 if (f->c[d]) 34 f -> c[d] -> fa = f; 35 tag -> fa = f -> fa; 36 if (tag -> fa -> c[0] == f) 37 tag -> fa -> c[0] = tag; 38 else tag -> fa -> c[1] = tag; 39 f -> fa = tag; 40 tag -> c[anti] = f; 41 upd(f); 42 } 43 inline bool f(Node *tag){return tag->fa->c[1] == tag;} 44 inline void splay(Node *tag,Node *goal) 45 { 46 while(tag->fa != goal){ 47 if(tag->fa->fa == goal) 48 zig(tag,f(tag)); 49 else{ 50 if(f(tag) == f(tag->fa)) 51 zig(tag->fa,f(tag->fa)),zig(tag,f(tag)); 52 else 53 zig(tag,f(tag)),zig(tag,f(tag)); 54 } 55 } 56 upd(tag); 57 } 58 inline Node *search(int key) 59 { 60 Node *tag = root->c[0]; 61 while (tag && (key <= tag->lsz()||key > tag -> lsz() + tag -> cnt)) 62 { 63 if (key > tag ->lsz()+tag->cnt) 64 { 65 key -= tag->lsz()+tag->cnt; tag = tag->c[1]; 66 } 67 else tag = tag -> c[0]; 68 } 69 return tag; 70 } 71 public: 72 Splay() 73 { 74 root = new Node(‘#‘,NULL); Node *tmp = new Node(‘^‘,root); root ->c[0] = tmp; upd(tmp); 75 } 76 void insert(char *s) 77 { 78 Node *chr = new Node(s[0],NULL),*tmp,*now,*tag = root->c[0]; 79 tmp = now = chr; chr -> size = a; 80 for (int i = 1;i < a;++i) 81 { 82 now = new Node(s[i],tmp); 83 tmp -> c[1] = now; now -> size = a-i; 84 tmp = now; 85 } 86 Node *z = tag -> c[1]; 87 while (z && z->c[0]) z = z->c[0]; 88 if (z) 89 { 90 splay(z,tag); 91 z -> c[0] = chr; chr -> fa = z; 92 upd(z); 93 } 94 else 95 { 96 tag -> c[1] = chr; chr -> fa = tag; 97 upd(tag); 98 } 99 } 100 void trans(int x) {Node *tag = search(x); splay(tag,root);} 101 void erase(int l) 102 { 103 Node *tag = root->c[0]; if (!tag) return; 104 Node *end = search(tag->lsz()+tag->cnt+l+1); 105 if (end){splay(end,tag); end -> c[0] = NULL; upd(end);} 106 else tag -> c[1] = NULL; 107 upd(tag); 108 } 109 void print(int l) 110 { 111 Node *tag = root->c[0]; 112 for (int i = 1;i <= l;++i) 113 { 114 Node *tmp = search(p+i); 115 splay(tmp,tag); 116 putchar(tmp -> ch); 117 } 118 putchar(‘\n‘); 119 } 120 }tree; 121 int main() 122 { 123 freopen("1507.in","r",stdin); 124 freopen("1507.out","w",stdout); 125 scanf("%d",&t); 126 while (t--) 127 { 128 scanf("%s %d",cmd,&a); 129 if (cmd[0] == ‘I‘) 130 { 131 char c; 132 for (int i = 0;i<a;) 133 { 134 while ((c = getchar())==10||c == 13); 135 s[i++] = c; 136 } 137 tree.insert(s); continue; 138 } 139 if (cmd[0] == ‘M‘) 140 { 141 tree.trans(a+1); p = a + 1; continue; 142 } 143 if (cmd[0] == ‘D‘) 144 { 145 tree.erase(a); continue; 146 } 147 if (cmd[0] == ‘G‘) 148 { 149 tree.print(a); continue; 150 } 151 if (cmd[0] == ‘P‘) 152 { 153 tree.trans(--p); continue; 154 } 155 if(cmd[0] == ‘N‘) 156 { 157 tree.trans(++ p); continue; 158 } 159 } 160 fclose(stdin); fclose(stdout); 161 return 0; 162 }
时间: 2024-10-11 06:42:42