NOI2003]文本编辑器
1 in: 2 15 3 Insert 26 4 abcdefghijklmnop 5 qrstuv wxy 6 Move 15 7 Delete 11 8 Move 5 9 Insert 1 10 ^ 11 Next 12 Insert 1 13 _ 14 Next 15 Next 16 Insert 4 17 .\/. 18 Get 4 19 Prev 20 Insert 1 21 ^ 22 Move 0 23 Get 22 24 25 out: 26 .\/. 27 abcde^_^f.\/.ghijklmno
1 in: 2 15 3 Insert 26 4 abcdefghijklmnop 5 qrstuv wxy 6 Move 15 7 Delete 11 8 Move 5 9 Insert 1 10 ^ 11 Next 12 Insert 1 13 _ 14 Next 15 Next 16 Insert 4 17 .\/. 18 Get 4 19 Prev 20 Insert 1 21 ^ 22 Move 0 23 Get 22 24 25 out: 26 .\/. 27 abcde^_^f.\/.ghijklmno
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e3+10; 4 struct node{ 5 int ne,siz;//每一块数组的后继以及大小 6 char a[maxn<<1]; 7 }b[maxn<<2]; 8 int n; 9 int bg[maxn<<2],cnt,cp;//属于哪个块、第几个块以及题目光标位置 10 int addi() 11 { 12 cnt++; 13 return bg[cnt]; 14 } 15 void dele(int x) 16 { 17 bg[cnt]=x; 18 cnt--; 19 } 20 void init() 21 { 22 for(int i=1;i<(maxn<<2);++i) bg[i]=i; 23 cnt=1; 24 b[1].siz=0,b[1].ne=-1; 25 } 26 void add(int x,int y,int len,char c[])//在第x块后添加一个编号为y的块,长度为len 27 { 28 if(y!=-1) 29 { 30 b[y].ne=b[x].ne,b[y].siz=len; 31 memcpy(b[y].a,c,len); 32 } 33 b[x].ne=y; 34 } 35 void merge(int x,int y)//将第x块和第y块合并 36 { 37 memcpy(b[x].a+b[x].siz,b[y].a,b[y].siz); 38 b[x].siz+=b[y].siz,b[x].ne=b[y].ne; 39 dele(y); 40 } 41 void split(int k,int pos)//将第k块从pos处分割 42 { 43 if(k==-1||pos==b[k].siz) return ; 44 add(k,addi(),b[k].siz-pos,b[k].a+pos); 45 b[k].siz=pos; 46 } 47 int pos(int &x)//寻找当前光标所在的块和块内位置 48 { 49 int now=1; 50 while(now!=-1&&x>b[now].siz) x-=b[now].siz,now=b[now].ne; 51 return now; 52 } 53 void insert(int p,int len,char c[])//在p位置之后插入长度为len的字符串 54 { 55 int now=pos(p); 56 split(now,p); 57 //cout<<now<<" "<<b[now].ne<<" "<<b[now].siz<<endl; 58 int tot=0,nb,st=now; 59 while(tot+maxn<=len)//维护块状链表平衡 60 { 61 nb=addi(); 62 add(now,nb,maxn,c+tot); 63 tot+=maxn; 64 now=nb; 65 } 66 if(len-tot) 67 nb=addi(),add(now,nb,len-tot,c+tot); 68 if(b[now].siz+b[nb].siz<maxn&&nb!=-1)//不用对整个链表进行判断,部分maintain 69 merge(now,nb),nb=b[now].ne; 70 if(b[st].siz+b[b[st].ne].siz<maxn&&b[st].ne!=-1)//同理 71 merge(st,b[st].ne); 72 //cout<<"insert "<<now<<" "<<b[now].siz<<" "<<b[now].ne<<endl; 73 } 74 void erase(int p,int len)//在p位置之后删除长度为len的字符串 75 { 76 int now=pos(p); 77 split(now,p); 78 int ne=b[now].ne; 79 //cout<<"pp "<<now<<" "<<cnt<<" "<<b[now].ne<<endl; 80 while(ne!=-1&&len>b[ne].siz) 81 len-=b[ne].siz,ne=b[ne].ne; 82 split(ne,len); 83 ne=b[ne].ne; 84 for(int i=b[now].ne;i!=ne;i=b[now].ne) 85 b[now].ne=b[i].ne,dele(i); 86 //cout<<"pp2 "<<now<<" "<<cnt<<" "<<b[now].ne<<" "<<ne<<endl; 87 while(b[now].siz+b[ne].siz<maxn&&ne!=-1)//不用对整个链表进行判断,部分maintain 88 merge(now,ne),ne=b[now].ne; 89 } 90 char ss[20000000],s[1000]; 91 void get(int p,int len)//输出p位置后长度为len的字符串 92 { 93 int k=pos(p); 94 int tot=b[k].siz-p; 95 if(len<tot) tot=len; 96 memcpy(ss,b[k].a+p,tot); 97 int now=b[k].ne; 98 while(now!=-1&&len>=tot+b[now].siz) 99 { 100 memcpy(ss+tot,b[now].a,b[now].siz); 101 tot+=b[now].siz,now=b[now].ne; 102 } 103 if(len-tot>0&&now!=-1) 104 memcpy(ss+tot,b[now].a,len-tot); 105 //cout<<"get "<<now<<endl; 106 for(int i=0;i<len;++i) cout<<ss[i]; 107 cout<<endl; 108 } 109 int main() 110 { 111 init(); 112 scanf("%d",&n); 113 while(n--) 114 { 115 int len; 116 scanf("%s",s); 117 if(s[0]=='M') 118 { 119 scanf("%d",&cp); 120 } 121 else if(s[0]=='I') 122 { 123 scanf("%d",&len);getchar(); 124 for(int i=0;i<len;++i) 125 { 126 ss[i]=getchar(); 127 if(ss[i]<32||ss[i]>126) --i; 128 } 129 insert(cp,len,ss); 130 } 131 else if(s[0]=='D') 132 { 133 scanf("%d",&len); 134 erase(cp,len); 135 } 136 else if(s[0]=='G') 137 { 138 scanf("%d",&len); 139 get(cp,len); 140 } 141 else if(s[0]=='P') 142 { 143 cp--; 144 } 145 else if(s[0]=='N') 146 { 147 cp++; 148 } 149 // cout<<"zzzzz "<<n<<" pos "<<cp<<" "<<s[0]<<endl; 150 // get(cp,2); 151 } 152 return 0; 153 }