AHOI2006 文本編輯器(BZOJ1269)

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=1269php

 

1269: [AHOI2006]文本編輯器editor

Time Limit: 10 Sec  Memory Limit: 162 MB

Description

這些日子,可可不和卡卡一塊兒玩了,原來可可正廢寢忘食的想作一個簡單而高效的文本編輯器。你能幫助他嗎?爲了明確任務目標,可可對「文本編輯器」作了一個抽象的定義: 文本:由0個或多個字符構成的序列。這些字符的ASCII碼在閉區間[32, 126]內,也就是說,這些字符均爲可見字符或空格。光標:在一段文本中用於指示位置的標記,能夠位於文本的第一個字符以前,文本的最後一個字符以後或文 本的某兩個相鄰字符之間。文本編輯器:爲一個能夠對一段文本和該文本中的一個光標進行以下七條操做的程序。若是這段文本爲空,咱們就說這個文本編輯器是空 的。 編寫一個程序: 創建一個空的文本編輯器。 從輸入文件中讀入一些操做指令並執行。 對全部執行過的GET操做,將指定的內容寫入輸出文件。node

Input

輸入文件中第一行是指令條數N,如下是須要執行的N個操做。除了回車符以外,輸入文件的全部字符的ASCII碼都在閉區間[32, 126]內。且行尾沒有空格。ios

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

鳴謝seter從新制做數據ui

 

這題是道不錯的平衡樹題。。就是初始時建樹有些麻煩,這題用鏈式建樹會方便。spa

。。坑爹的是我沒加讀入優化交了TLE。。加了讀入優化以後1368ms。。code

 

Codes:blog

  1 #include<set>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<iostream>
  6 #include<algorithm>
  7 using namespace std;
  8 const int N = 1024 * 1024 * 2 + 10;
  9 #define fa(i) (T[i].p)
 10 #define L(i) (T[i].s[0])
 11 #define R(i) (T[i].s[1])
 12 #define Key (L(R(root)))
 13 #define Loc(i) (T[fa(i)].s[1]==i)
 14 #define For(i,n) for(int i=1;i<=n;i++)
 15 #define Rep(i,l,r) for(int i=l;i<=r;i++)
 16 #define Sets(a,b,c) {if(a) T[a].s[c] = b; if(b) fa(b) = a;}
 17 struct tnode{
 18     int s[2],p,size,rev;
 19     char v;
 20 }T[N];
 21 
 22 char op[10],str[N];
 23 int n,tot,len,root,cur;
 24 
 25 void Update(int i){
 26     T[i].size = T[L(i)].size + T[R(i)].size + 1;
 27 }
 28 
 29 void Pushdown(int i){
 30     if(T[i].rev){
 31         if(L(i)) T[L(i)].rev ^= 1;
 32         if(R(i)) T[R(i)].rev ^= 1;
 33         swap(L(i),R(i));
 34         T[i].rev = 0;
 35     }    
 36 }
 37 
 38 void Build(int l,int r,int p,int &i){
 39     if(l>r) return;
 40     T[i=++tot].p = p;T[i].size = 1;T[i].rev = 0;
 41     int m = (l+r)>>1;
 42     T[i].v = str[m];
 43     Build(l,m-1,i,L(i));Build(m+1,r,i,R(i));
 44     Update(i);
 45 }
 46 
 47 int Rank(int kth,int i){
 48     Pushdown(i);
 49     if(T[L(i)].size + 1 == kth)  return i;
 50     else if(T[L(i)].size >= kth) return Rank(kth,L(i));
 51     else                         return Rank(kth - T[L(i)].size - 1 , R(i));
 52 }
 53 
 54 void Rot(int x){
 55     int y = fa(x) , z = fa(y);
 56     int lx = Loc(x) , ly = Loc(y);
 57     Pushdown(y);Pushdown(x);
 58     Sets(y,T[x].s[!lx],lx);
 59     Sets(z,x,ly);
 60     Sets(x,y,!lx);
 61     Update(y);
 62 }
 63 
 64 void Splay(int i,int goal){
 65     while(fa(i)!=goal){
 66         if(fa(fa(i))!=goal) Rot(fa(i));
 67         Rot(i);
 68     }
 69     Update(i);
 70     if(!goal) root = i;
 71 }
 72 
 73 int read(){
 74     int num = 0; char ch = getchar();
 75     while(ch>'9'||ch<'0') ch = getchar();
 76     while(ch>='0'&&ch<='9'){
 77         num = num * 10 + ch - '0';
 78         ch = getchar();
 79     }
 80     return num;
 81 }
 82 
 83 int main(){
 84     n = read();
 85     T[root=++tot].p = 0;R(root)=++tot;T[R(root)].p = root;
 86     Update(R(root));Update(root);
 87     For(i,n){
 88         scanf("%s",&op);
 89         if(op[0]=='I'){
 90             len = read();
 91             gets(str);
 92             Splay(Rank(cur+1,root),0);
 93             Splay(Rank(cur+2,root),root);
 94             Build(0,len-1,R(root),Key);
 95             Update(R(root));Update(root);
 96         }else
 97         if(op[0]=='M'){
 98             len = read();cur = len;
 99         }else
100         if(op[0]=='D'){
101             len = read();
102             Splay(Rank(cur+1,root),0);
103             Splay(Rank(cur+len+2,root),root);
104             T[Key].p = 0;T[R(root)].s[0] = 0;
105             Update(R(root));Update(root);
106         }else
107         if(op[0]=='N') cur++;else
108         if(op[0]=='P') cur--;else
109         if(op[0]=='G'){
110             Splay(Rank(cur+2,root),0);
111             printf("%c\n",T[root].v);
112         }else
113         if(op[0]=='R'){
114             len = read();
115             Splay(Rank(cur+1,root),0);
116             Splay(Rank(cur+len+2,root),root);
117             T[Key].rev ^= 1;
118         }
119     }
120     return 0;
121 }
相關文章
相關標籤/搜索