BZOJ 1507 Editor

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 }
View Code

 

posted @ 2015-02-16 19:59  lmxyy  阅读(165)  评论(0编辑  收藏  举报