首页 > 代码库 > AHOI2006文本编辑器editor
AHOI2006文本编辑器editor
1269: [AHOI2006]文本编辑器editor
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1885 Solved: 683
[Submit][Status]
Description
这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间。文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空的。 编写一个程序:? 建立一个空的文本编辑器。? 从输入文件中读入一些操作指令并执行。? 对所有执行过的GET操作,将指定的内容写入输出文件。
Input
输入文件中第一行是指令条数N,以下是需要执行的N个操作。除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。
Output
依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。
Sample Input
Insert 13
Balanced eert
Move 2
Delete 5
Next
Insert 7
editor
Move 0
Get
Move 11
Rotate 4
Get
Sample Output
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重新制作数据
题解:
和NOI2003的editor差不多,只是多了个rotate操作,对于splay操作,只需要在 find 时先做一次 pushdown即可
这次没有TLE,真爽。。。
代码:
1 {$inline on} 2 {$M 1000000000,0,maxlongint} 3 const maxn=2000000+1000; 4 var s,fa:array[0..maxn] of longint; 5 rev:array[0..maxn] of boolean; 6 v:array[0..maxn] of char; 7 c:array[0..maxn,0..1] of longint; 8 i,j,n,m,x,y,z,tot,rt,now,l,r:longint; 9 ch:char; 10 st,st2:ansistring; 11 procedure swap(var x,y:longint);inline; 12 var t:longint; 13 begin 14 t:=x;x:=y;y:=t; 15 end; 16 procedure pushup(x:longint);inline; 17 begin 18 s[x]:=s[c[x,0]]+s[c[x,1]]+1; 19 end; 20 procedure pushdown(x:longint);inline; 21 var l,r:longint; 22 begin 23 l:=c[x,0];r:=c[x,1]; 24 if rev[x] then 25 begin 26 swap(c[x,0],c[x,1]); 27 rev[l]:=not(rev[l]); 28 rev[r]:=not(rev[r]); 29 rev[x]:=false; 30 end; 31 end; 32 procedure rotate(x:longint;var k:longint);inline; 33 var y,z,l,r:longint; 34 begin 35 y:=fa[x];z:=fa[y]; 36 l:=ord(c[y,1]=x);r:=l xor 1; 37 if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x; 38 fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y; 39 c[y,l]:=c[x,r];c[x,r]:=y; 40 pushup(y);pushup(x); 41 end; 42 procedure splay(x:longint;var k:longint);inline; 43 var y,z:longint; 44 begin 45 while x<>k do 46 begin 47 y:=fa[x];z:=fa[y]; 48 if y<>k then 49 if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k) 50 else rotate(y,k); 51 rotate(x,k); 52 end; 53 end; 54 function find(x,rank:longint):longint;inline; 55 var l,r:longint; 56 begin 57 pushdown(x); 58 l:=c[x,0];r:=c[x,1]; 59 if s[l]+1=rank then exit(x) 60 else if s[l]>=rank then exit(find(l,rank)) 61 else exit(find(r,rank-s[l]-1)); 62 end; 63 procedure main; 64 begin 65 readln(n); 66 l:=maxn-100+1;r:=maxn-100+2; 67 rt:=l; 68 c[l,1]:=r;fa[r]:=l;s[l]:=2;s[r]:=1; 69 now:=1;tot:=0; 70 for i:=1 to n do 71 begin 72 read(ch); 73 case ch of 74 ‘P‘:begin 75 readln; 76 dec(now); 77 end; 78 ‘N‘:begin 79 readln; 80 inc(now); 81 end; 82 ‘M‘:begin 83 while ch<>‘ ‘ do read(ch);readln(x); 84 now:=x+1; 85 end; 86 ‘I‘:begin 87 while ch<>‘ ‘ do read(ch);readln(m); 88 readln(st);while length(st)<m do begin readln(st2);st:=st+st2;end; 89 for j:=1 to m do begin inc(tot);fa[tot]:=tot-1;v[tot]:=st[j];s[tot]:=m-j+1;c[tot,0]:=0;if j<>m then c[tot,1]:=tot+1 else c[tot,1]:=0;end; 90 x:=find(rt,now);y:=find(rt,now+1); 91 splay(x,rt);splay(y,c[x,1]); 92 c[y,0]:=tot-m+1;fa[tot-m+1]:=y; 93 pushup(y);pushup(x); 94 end; 95 ‘D‘:begin 96 while ch<>‘ ‘ do read(ch);readln(m); 97 x:=find(rt,now);y:=find(rt,now+m+1); 98 splay(x,rt);splay(y,c[x,1]); 99 z:=c[y,0];fa[z]:=0;c[y,0]:=0;100 pushup(y);pushup(x);101 end;102 ‘R‘:begin103 while ch<>‘ ‘ do read(ch);readln(m);104 x:=find(rt,now);y:=find(rt,now+m+1);105 splay(x,rt);splay(y,c[x,1]);106 z:=c[y,0];107 rev[z]:=not(rev[z]);108 end;109 ‘G‘:begin110 readln;111 writeln(v[find(rt,now+1)]);112 end;113 end;114 end;115 end;116 begin117 assign(input,‘input.txt‘);assign(output,‘output.txt‘);118 reset(input);rewrite(output);119 main;120 close(input);close(output);121 end.