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 }
View Code
原文地址:https://www.cnblogs.com/adelalove/p/11782327.html