Bzoj1269 [AHOI2006]文本编辑器editor
Submit: 3678 Solved: 1380
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
Splay树
肝过维修数列之后,这文本编辑器还是比较好写的。
总之就是各种模拟操作。
第一遍数组开小了T了,开大数组之后WAWAWA
左看右看找不出错,就试着改读入格式。
调了半个多小时无果,觉得有哪里不对。
好像每输出一个字符是要换行的……说好的“对应输入文件中每条GET指令的输出,不得有任何多余的字符”呢?
加个换行就过了,理论上是2A(强行)
不过改了读入之后,时间从2000ms降到了1700+ms (虽然还是好大)
原代码:
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=2100010; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 struct node{ 16 int ch[2]; 17 bool rev; 18 int w,fa,size; 19 }t[mxn]; 20 int a[mxn]; 21 int root,cnt=0; 22 int cpos=0;//模拟光标 23 void pushdown(int x){ 24 if(t[x].rev){ 25 swap(t[x].ch[0],t[x].ch[1]); 26 t[t[x].ch[0]].rev^=1; t[t[x].ch[1]].rev^=1; 27 t[x].rev=0; 28 } 29 return; 30 } 31 void pushup(int x){ 32 t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+1;return; 33 } 34 void rotate(int x,int &k){ 35 // printf("rotate:%d %d\n",x,k); 36 int y=t[x].fa,z=t[y].fa,lc,rc; 37 if(t[y].ch[0]==x)lc=0;else lc=1; rc=lc^1; 38 if(y==k)k=x; 39 else t[z].ch[t[z].ch[1]==y]=x; 40 t[x].fa=z;t[y].fa=x;t[t[x].ch[rc]].fa=y; 41 t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y; 42 pushup(y); 43 // pushup(x); 44 return; 45 } 46 void Splay(int x,int &k){ 47 pushdown(x); 48 while(x!=k){ 49 int y=t[x].fa;int z=t[y].fa; 50 if(y!=k) 51 if((t[z].ch[0]==y)^(t[y].ch[0]==x))rotate(x,k); 52 else rotate(y,k); 53 rotate(x,k); 54 } 55 pushup(x); 56 return; 57 } 58 int st[mxn],top=0; 59 60 int newnode(int x){ 61 int tmp; 62 if(top)tmp=st[top--]; 63 else tmp=++cnt; 64 t[tmp].ch[0]=t[tmp].ch[1]=0; 65 t[tmp].size=1;t[tmp].w=x; 66 t[tmp].rev=0; 67 return tmp; 68 } 69 int Build(int l,int r,int fa){ 70 if(l>r)return 0; 71 int mid=(l+r)>>1; 72 int rt=newnode(a[mid]); 73 t[rt].ch[0]=Build(l,mid-1,rt); 74 t[rt].ch[1]=Build(mid+1,r,rt); 75 t[rt].fa=fa; 76 pushup(rt); 77 return rt; 78 } 79 void split(int x,int y){ 80 Splay(x,root); 81 Splay(y,t[x].ch[1]); 82 return; 83 } 84 int find(int x,int w){ 85 if(t[x].rev)pushdown(x); 86 // printf("rt:%d lc:%d rc:%d sz:%d %d\n",x,t[x].ch[0],t[x].ch[1],t[x].size,w); 87 if(w<=t[t[x].ch[0]].size)return find(t[x].ch[0],w); 88 if(w==t[t[x].ch[0]].size+1)return x; 89 return find(t[x].ch[1],w-t[t[x].ch[0]].size-1); 90 } 91 void insert(int pos){ 92 int n=read(); 93 for(int i=1;i<=n;i++) 94 a[i]=getchar(); 95 int tmp=Build(1,n,0); 96 int x=find(root,pos),y=find(root,pos+1); 97 split(x,y); 98 t[y].ch[0]=tmp; 99 t[tmp].fa=y; 100 pushup(y);pushup(x); 101 // printf("finished\n"); 102 // for(int i=1;i<=n;i++)printf("%c",a[i]); 103 // printf("\n"); 104 return; 105 } 106 void del(int &x){ 107 if(!x)return; 108 // printf("del:%d\n",x); 109 t[t[x].fa].size-=t[x].size; 110 t[x].fa=0; 111 st[++top]=x; 112 del(t[x].ch[0]);del(t[x].ch[1]); 113 x=0; 114 return; 115 } 116 void Dele(int pos,int len){ 117 int x=find(root,pos),y=find(root,pos+len+1); 118 // printf("%d %d\n",x,y); 119 split(x,y); 120 del(t[y].ch[0]); 121 return; 122 } 123 void reverse(int pos,int len){ 124 int x=find(root,pos),y=find(root,pos+len+1); 125 split(x,y); 126 t[t[y].ch[0]].rev^=1; 127 pushdown(t[y].ch[0]); 128 return; 129 } 130 void Debug(int x){ 131 if(t[x].ch[0])Debug(t[x].ch[0]); 132 if(t[x].w)printf("%c",t[x].w); 133 if(t[x].ch[1])Debug(t[x].ch[1]); 134 return; 135 } 136 void Get(){ 137 // for(int i=0;i<=cnt;i++){ 138 // printf("rt:%d lc:%d rc:%d\n",i,t[i].ch[0],t[i].ch[1]); 139 // printf("fa:%d sz:%d w:%d\n",t[i].fa,t[i].size,t[i].w); 140 // printf("\n"); 141 // } 142 143 int x=find(root,cpos+1); 144 if(t[x].w)printf("%c\n",t[x].w); 145 else puts(" "); 146 return; 147 } 148 int n; 149 int main(){ 150 int i,j,x; 151 int st=1,ed=2; 152 n=read(); 153 char op[50]; 154 cpos=1; 155 root=Build(1,2,0); 156 // printf("fin\n"); 157 st=find(root,1); 158 ed=find(root,2); 159 while(n--){ 160 scanf("%s",op); 161 switch(op[0]){ 162 case 'M':{ 163 x=read(); 164 cpos=x+1; 165 break; 166 } 167 case 'I':{ 168 insert(cpos); 169 break; 170 } 171 case 'D':{ 172 x=read(); 173 Dele(cpos,x); 174 break; 175 } 176 case 'R':{ 177 x=read(); 178 reverse(cpos,x); 179 break; 180 } 181 case 'G':{Get();break;} 182 case 'P':{cpos--;break;} 183 case 'N':{cpos++;break;} 184 // case 'K':{printf("root:%d\n",root);Debug(root);break;} 185 } 186 } 187 return 0; 188 } 189
从阿当学长那学到的读入方式:
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=2100010; 9 struct node{ 10 int ch[2]; 11 bool rev; 12 int w,fa,size; 13 }t[mxn]; 14 char a[2100000]; 15 int root,cnt=0; 16 int cpos=0;//模拟光标 17 void pushdown(int x){ 18 if(t[x].rev){ 19 swap(t[x].ch[0],t[x].ch[1]); 20 t[t[x].ch[0]].rev^=1; t[t[x].ch[1]].rev^=1; 21 t[x].rev=0; 22 } 23 return; 24 } 25 void pushup(int x){ 26 t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+1;return; 27 } 28 void rotate(int x,int &k){ 29 int y=t[x].fa,z=t[y].fa,lc,rc; 30 if(t[y].ch[0]==x)lc=0;else lc=1; rc=lc^1; 31 if(y==k)k=x; 32 else t[z].ch[t[z].ch[1]==y]=x; 33 t[x].fa=z;t[y].fa=x;t[t[x].ch[rc]].fa=y; 34 t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y; 35 pushup(y); 36 return; 37 } 38 void Splay(int x,int &k){ 39 pushdown(x); 40 while(x!=k){ 41 int y=t[x].fa;int z=t[y].fa; 42 if(y!=k) 43 if((t[z].ch[0]==y)^(t[y].ch[0]==x))rotate(x,k); 44 else rotate(y,k); 45 rotate(x,k); 46 } 47 pushup(x); 48 return; 49 } 50 int st[mxn],top=0; 51 52 int newnode(int x){ 53 int tmp; 54 if(top)tmp=st[top--]; 55 else tmp=++cnt; 56 t[tmp].ch[0]=t[tmp].ch[1]=0; 57 t[tmp].size=1;t[tmp].w=x; 58 t[tmp].rev=0; 59 return tmp; 60 } 61 int Build(int l,int r,int fa){ 62 if(l>r)return 0; 63 int mid=(l+r)>>1; 64 int rt=newnode(a[mid]); 65 t[rt].ch[0]=Build(l,mid-1,rt); 66 t[rt].ch[1]=Build(mid+1,r,rt); 67 t[rt].fa=fa; 68 pushup(rt); 69 return rt; 70 } 71 void split(int x,int y){ 72 Splay(x,root); 73 Splay(y,t[x].ch[1]); 74 return; 75 } 76 int find(int x,int w){ 77 if(t[x].rev)pushdown(x); 78 if(w<=t[t[x].ch[0]].size)return find(t[x].ch[0],w); 79 if(w==t[t[x].ch[0]].size+1)return x; 80 return find(t[x].ch[1],w-t[t[x].ch[0]].size-1); 81 } 82 void Debug(int x){ 83 if(t[x].ch[0])Debug(t[x].ch[0]); 84 if(t[x].w)printf("%c",t[x].w); 85 if(t[x].ch[1])Debug(t[x].ch[1]); 86 return; 87 } 88 void insert(int pos){ 89 int n;scanf("%d%*c",&n); 90 gets(a+1); 91 int tmp=Build(1,n,0); 92 int x=find(root,pos),y=find(root,pos+1); 93 split(x,y); 94 t[y].ch[0]=tmp; 95 t[tmp].fa=y; 96 pushup(y);pushup(x); 97 return; 98 } 99 void del(int &x){ 100 if(!x)return; 101 t[t[x].fa].size-=t[x].size; 102 t[x].fa=0; 103 st[++top]=x; 104 del(t[x].ch[0]);del(t[x].ch[1]); 105 x=0; 106 return; 107 } 108 void Dele(int pos,int len){ 109 int x=find(root,pos),y=find(root,pos+len+1); 110 split(x,y); 111 del(t[y].ch[0]); 112 return; 113 } 114 void reverse(int pos,int len){ 115 int x=find(root,pos),y=find(root,pos+len+1); 116 split(x,y); 117 t[t[y].ch[0]].rev^=1; 118 pushdown(t[y].ch[0]); 119 return; 120 } 121 122 void Get(){ 123 int x=find(root,cpos+1); 124 if(t[x].w)printf("%c\n",t[x].w); 125 else puts(" "); 126 return; 127 } 128 int n; 129 int main(){ 130 int i,j,x;int st=1,ed=2; 131 scanf("%d%*c",&n); 132 char op[50]; 133 cpos=1; 134 a[1]=a[2]=0; 135 root=Build(1,2,0); 136 st=find(root,1);ed=find(root,2); 137 while(n--){ 138 scanf("%s%*c",op); 139 switch(op[0]){ 140 case 'M':{scanf("%d%*c",&x);cpos=x+1;break;} 141 case 'I':{insert(cpos);break;} 142 case 'D':{scanf("%d%*c",&x);Dele(cpos,x);break;} 143 case 'R':{scanf("%d%*c",&x);reverse(cpos,x);break;} 144 case 'G':{Get();break;} 145 case 'P':{cpos--;break;} 146 case 'N':{cpos++;break;} 147 } 148 } 149 return 0; 150 }