Bzoj1269 [AHOI2006]文本编辑器editor

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3678  Solved: 1380

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

 

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 }
View Code

 

posted @ 2017-01-06 17:30  SilverNebula  阅读(191)  评论(0编辑  收藏  举报
AmazingCounters.com