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 }

时间: 2024-10-11 06:42:42

BZOJ 1507 Editor的相关文章

BZOJ 1507 NOI2003 Editor Splay

题目大意: 1.将光标移动到某一位置 2.在光标后插入一段字符串 3.删除光标后的一段字符 4.输出光标后的一段字符 5.光标-- 6.光标++ 和1269很像的一道题,不过弱多了 几个问题需要注意: 1.插入的字符串中间居然会有回车!!没办法了,只能逐个字符进行读入,一旦读到'\n'或者'\r'就重新读入 2.题目描述中说Delete和Get操作后面一定会有足够的字符 纯属放P 连样例都没有足够的字符用来删除 所以删除时要和字符串长度取一个最小值 然后就水水地过去了~ 30%达成 今天是不是可

BZOJ 1507 NOI 2003 Editor Splay

题目大意:维护一种数据结构,它可以: 1.移动光标 2.在光标之后插入一段字符串 3.删除光标之后的n个字符 4.输出光标之后的n个字符 5.移动光标 思路:Splay,没什么特别的.但是有几个需要注意的地方.1.题中说:delete操作不会越界.但是其实有可能会越界,比如样例就越界了.. 2.输出的时候一定不要偷懒.我刚开始写的时候就把输出写成nlogn输出的了,然后果断T了吗,我还以为是哪里死循环了,结果是这里被卡了!以后再也不偷懒随便加logn了... CODE: #include <cs

bzoj 1507: [NOI2003]Editor

1 #include<cstdio> 2 #include<iostream> 3 #include<ext/rope> 4 using namespace std; 5 using namespace __gnu_cxx; 6 crope list; 7 int n,now; 8 char ch[10],ch1[3000005]; 9 int main() 10 { 11 scanf("%d",&n); 12 for(int i=1;i&l

BZOJ 1269: [AHOI2006]文本编辑器editor( splay )

splay..( BZOJ 1507 题目基本相同..双倍经验 ) ----------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i <

数据结构&#183;SPlay

Splay嘛是什么?网上一大堆教程我就懒得说了,毕竟自己表达能力超烂超烂的. 原理很简单,但是写起代码来就各种WARETLE了晕. 也没去看其他大神的Splay模版,然后就自己一边找题做一边摸索出一套适合自己的模版,打得顺手才好用嘛=v= BZOJ 1503 [Code] BZOJ 1500 [Code] BZOJ 1507 [Code] BZOJ 3223 [Code] BZOJ 1269 [Code] 大概就这些题了. 明天该搞LCT了.

BZOI 1507 [NOI2003] Editor

Background After trying to solve problem EDIT1(Editor) and being ****ed by Brainf**k, Blue Mary decided to set another difficult problem about editor. Description Some definations: Text: It's a sequence that consists characters whose ASCII code is in

【BZOJ】【1269】【AHOI2006】文本编辑器editor

Splay Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build.splay和Findkth这三个操作,我们可以实现一个splay(x,s)操作,使x结点旋转到s结点的下方(如果s为0则x旋转到根),这样可以方便地提取出要处理的区间. 这份模板我还是比较满意的,因为写的没那么长…… 1 /**************************************************************

1507: [NOI2003]Editor(块状链表)

1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 4157  Solved: 1677[Submit][Status][Discuss] Description Input 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例). 除了回车符之外,输入文件的所有字

BZOJ 1269 【AHOI2006】 文本编辑器editor

题目链接:文本编辑器editor 这道题没啥好说的,直接上\(Splay\)就行了,板子题-- 但是我某个地方忘了下放标记导致调了一晚上 保存一发板子: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define File(s) freopen(s".in","r",std