Bzoj1269 [AHOI2006]文本编辑器editor
Submit:?3678??Solved:?1380
Description
這些日子,可可不和卡卡一起玩了,原來可可正廢寢忘食的想做一個簡單而高效的文本編輯器。你能幫助他嗎?為了明確任務目標,可可對“文本編輯器”做了一個抽象的定義:???文本:由0個或多個字符構成的序列。這些字符的ASCII碼在閉區間[32, 126]內,也就是說,這些字符均為可見字符或空格。光標:在一段文本中用于指示位置的標記,可以位于文本的第一個字符之前,文本的最后一個字符之后或文本的某兩個相鄰字符之間。文本編輯器:為一個可以對一段文本和該文本中的一個光標進行如下七條操作的程序。如果這段文本為空,我們就說這個文本編輯器是空的。 編寫一個程序:? 建立一個空的文本編輯器。? 從輸入文件中讀入一些操作指令并執行。? 對所有執行過的GET操作,將指定的內容寫入輸出文件。
Input
輸入文件中第一行是指令條數N,以下是需要執行的N個操作。除了回車符之外,輸入文件的所有字符的ASCII碼都在閉區間[32, 126]內。且行尾沒有空格。
Output
依次對應輸入文件中每條GET指令的輸出,不得有任何多余的字符。
Sample Input
10Insert 13
Balanced eert
Move 2
Delete 5
Next
Insert 7
editor
Move 0
Get
Move 11
Rotate 4
Get
Sample Output
Bt
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重新制作數據
?
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?
轉載于:https://www.cnblogs.com/SilverNebula/p/6257151.html
總結
以上是生活随笔為你收集整理的Bzoj1269 [AHOI2006]文本编辑器editor的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POST中文乱码解决方案
- 下一篇: dotnet获取PDF文件的页数