描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1269
和BZOJ_1507很像的题,多了一个反转操作,还是Splay简单区间操作的模板题.
1269: [AHOI2006]文本编辑器editor
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3223 Solved: 1203
[Submit][Status][Discuss]
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
分析
之前的操作和BZOJ_1507相同,多了一个反转操作:
递归地将左右子树调换位置,为了节约时间,打上标记即可.
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int maxn=(1<<21)+5; 6 7 int n,at,cur,x; 8 char str[maxn],s[10]; 9 10 struct Splay{ 11 struct node{ 12 node* ch[2],*pa; 13 char v; int s; bool rev; 14 node(char v,node* t):v(v){ ch[0]=ch[1]=pa=t; s=1; rev=false; } 15 bool d() { return pa->ch[1]==this; } 16 void setc(node* t,bool d) { ch[d]=t; t->pa=this; } 17 void push_up() { s=ch[0]->s+ch[1]->s+1; } 18 void push_down(){//向下传递反转 19 if(rev){ 20 node* c0=ch[0],* c1=ch[1]; 21 setc(c1,0); setc(c0,1);//调换左右子树的位置(貌似可以直接用swap,但刚开始还是自己写吧) 22 ch[0]->rev^=true; ch[1]->rev^=true; 23 rev=false; 24 } 25 } 26 }*root,*null; 27 Splay(){ 28 null=new node('