AmazingCounters.com

AHOI2006 文本编辑器(BZOJ1269)

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1269

 

1269: [AHOI2006]文本编辑器editor

Time Limit: 10 Sec  Memory Limit: 162 MB

Description

这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文 本的某两个相邻字符之间。文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空 的。 编写一个程序: 建立一个空的文本编辑器。 从输入文件中读入一些操作指令并执行。 对所有执行过的GET操作,将指定的内容写入输出文件。

Input

输入文件中第一行是指令条数N,以下是需要执行的N个操作。除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。

Output

依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。

Sample Input

10
Insert 13
Balanced eert
Move 2
Delete 5
Next
Insert 7
editor
Move 0
Get
Move 11
Rotate 4
Get

Sample Output

B
t

HINT

对输入数据我们有如下假定: MOVE操作不超过50 000个,INSERT、DELETE和ROTATE操作作的总个数不超过6 000,GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。 所有INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。 DELETE操作、ROTATE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。 输入文件没有错误。

Source

鸣谢seter重新制作数据

 

这题是道不错的平衡树题。。就是初始时建树有些麻烦,这题用链式建树会方便。

。。坑爹的是我没加读入优化交了TLE。。加了读入优化之后1368ms。。

 

Codes:

  1 #include<set>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<iostream>
  6 #include<algorithm>
  7 using namespace std;
  8 const int N = 1024 * 1024 * 2 + 10;
  9 #define fa(i) (T[i].p)
 10 #define L(i) (T[i].s[0])
 11 #define R(i) (T[i].s[1])
 12 #define Key (L(R(root)))
 13 #define Loc(i) (T[fa(i)].s[1]==i)
 14 #define For(i,n) for(int i=1;i<=n;i++)
 15 #define Rep(i,l,r) for(int i=l;i<=r;i++)
 16 #define Sets(a,b,c) {if(a) T[a].s[c] = b; if(b) fa(b) = a;}
 17 struct tnode{
 18     int s[2],p,size,rev;
 19     char v;
 20 }T[N];
 21 
 22 char op[10],str[N];
 23 int n,tot,len,root,cur;
 24 
 25 void Update(int i){
 26     T[i].size = T[L(i)].size + T[R(i)].size + 1;
 27 }
 28 
 29 void Pushdown(int i){
 30     if(T[i].rev){
 31         if(L(i)) T[L(i)].rev ^= 1;
 32         if(R(i)) T[R(i)].rev ^= 1;
 33         swap(L(i),R(i));
 34         T[i].rev = 0;
 35     }    
 36 }
 37 
 38 void Build(int l,int r,int p,int &i){
 39     if(l>r) return;
 40     T[i=++tot].p = p;T[i].size = 1;T[i].rev = 0;
 41     int m = (l+r)>>1;
 42     T[i].v = str[m];
 43     Build(l,m-1,i,L(i));Build(m+1,r,i,R(i));
 44     Update(i);
 45 }
 46 
 47 int Rank(int kth,int i){
 48     Pushdown(i);
 49     if(T[L(i)].size + 1 == kth)  return i;
 50     else if(T[L(i)].size >= kth) return Rank(kth,L(i));
 51     else                         return Rank(kth - T[L(i)].size - 1 , R(i));
 52 }
 53 
 54 void Rot(int x){
 55     int y = fa(x) , z = fa(y);
 56     int lx = Loc(x) , ly = Loc(y);
 57     Pushdown(y);Pushdown(x);
 58     Sets(y,T[x].s[!lx],lx);
 59     Sets(z,x,ly);
 60     Sets(x,y,!lx);
 61     Update(y);
 62 }
 63 
 64 void Splay(int i,int goal){
 65     while(fa(i)!=goal){
 66         if(fa(fa(i))!=goal) Rot(fa(i));
 67         Rot(i);
 68     }
 69     Update(i);
 70     if(!goal) root = i;
 71 }
 72 
 73 int read(){
 74     int num = 0; char ch = getchar();
 75     while(ch>'9'||ch<'0') ch = getchar();
 76     while(ch>='0'&&ch<='9'){
 77         num = num * 10 + ch - '0';
 78         ch = getchar();
 79     }
 80     return num;
 81 }
 82 
 83 int main(){
 84     n = read();
 85     T[root=++tot].p = 0;R(root)=++tot;T[R(root)].p = root;
 86     Update(R(root));Update(root);
 87     For(i,n){
 88         scanf("%s",&op);
 89         if(op[0]=='I'){
 90             len = read();
 91             gets(str);
 92             Splay(Rank(cur+1,root),0);
 93             Splay(Rank(cur+2,root),root);
 94             Build(0,len-1,R(root),Key);
 95             Update(R(root));Update(root);
 96         }else
 97         if(op[0]=='M'){
 98             len = read();cur = len;
 99         }else
100         if(op[0]=='D'){
101             len = read();
102             Splay(Rank(cur+1,root),0);
103             Splay(Rank(cur+len+2,root),root);
104             T[Key].p = 0;T[R(root)].s[0] = 0;
105             Update(R(root));Update(root);
106         }else
107         if(op[0]=='N') cur++;else
108         if(op[0]=='P') cur--;else
109         if(op[0]=='G'){
110             Splay(Rank(cur+2,root),0);
111             printf("%c\n",T[root].v);
112         }else
113         if(op[0]=='R'){
114             len = read();
115             Splay(Rank(cur+1,root),0);
116             Splay(Rank(cur+len+2,root),root);
117             T[Key].rev ^= 1;
118         }
119     }
120     return 0;
121 }

 

posted @ 2014-07-30 14:05  ZJDx1998  阅读(183)  评论(0编辑  收藏  举报