1507: [NOI2003]Editor(块状链表)

2018-06-17 21:27:23来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

1507: [NOI2003]Editor

Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 4157  Solved: 1677
[Submit][Status][Discuss]

Description

Input

输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例)。 除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。 这里我们有如下假定: ? MOVE操作不超过50000个,INSERT和DELETE操作的总个数不超过4000,PREV和NEXT操作的总个数不超过200000。 ? 所有INSERT插入的字符数之和不超过2M(1M=1024*1024),正确的输出文件长度不超过3M字节。 ? DELETE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作必然不会试图把光标移动到非法位置。 ? 输入文件没有错误。 对C++选手的提示:经测试,最大的测试数据使用fstream进行输入有可能会比使用stdio慢约1秒。

Output

输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。

Sample Input

15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22

Sample Output

.\/.
abcde^_^f.\/.ghijklmno

 

 

code

  1 #include<cstdio>
  2 #include<cstring>
  3 
  4 const int MAXL = 2100000; 
  5 const int Block_size = 5010; 
  6 const int Block_num = 600; 
  7 int Number[Block_num],Tot;
  8 int nxt[Block_num],siz[Block_num]; 
  9 char data[Block_num][Block_size]; 
 10 char str[MAXL],s[20];
 11 
 12 void Init() {
 13     for (int i=1; i<Block_num; ++i) 
 14         Number[i] = i;
 15     Tot = 1;
 16     nxt[0] = -1;siz[0] = 0; 
 17 }
 18 int Getnum() {
 19     return Number[Tot++];
 20 } 
 21 void Delnum(int x) {
 22     Number[--Tot] = x;
 23 }
 24 int find(int &pos) {
 25     int k = 0;
 26     while (k != -1 && pos > siz[k]) {
 27         pos -= siz[k];
 28         k = nxt[k];
 29     }
 30     return k;
 31 }
 32 void Madenews(int cur,int news,int num,char str[]) {
 33     if (news!=-1) {
 34         nxt[news] = nxt[cur];
 35         siz[news] = num;
 36         memcpy(data[news],str,num);
 37     }
 38     nxt[cur] = news;
 39 } 
 40 void split(int cur,int pos) {
 41     if (cur==-1 || pos==siz[cur]) return ;
 42     int news = Getnum();
 43     Madenews(cur,news,siz[cur]-pos,data[cur]+pos);
 44     siz[cur] = pos;
 45 } 
 46 void Merge(int x,int y) {
 47     memcpy(data[x]+siz[x],data[y],siz[y]);
 48     siz[x] += siz[y];
 49     nxt[x] = nxt[y];
 50     Delnum(y);
 51 } 
 52 void Maintain() {
 53     int cur = 0; 
 54     while (cur != -1) { 
 55         int p = nxt[cur];
 56         while (p != -1 && siz[cur] + siz[p] <= Block_size) {
 57             Merge(cur,p);
 58             p = nxt[cur];
 59         }
 60         cur = nxt[cur];
 61     }
 62 }
 63 void Insert(int pos,int num,char str[]) {
 64     int cur = find(pos);
 65     split(cur,pos);
 66     int cnt = 0;
 67     while (cnt + Block_size <= num) {
 68         int news = Getnum();
 69         Madenews(cur,news,Block_size,str+cnt);
 70         cur = news;
 71         cnt += Block_size;
 72     }
 73     if (num - cnt) {
 74         int news = Getnum();
 75         Madenews(cur,news,num-cnt,str+cnt);
 76     } 
 77     Maintain();
 78 }
 79 void Erase(int pos,int num) {
 80     int cur = find(pos);
 81     split(cur,pos);
 82     int p = nxt[cur]; 
 83     while (p != -1 && num > siz[p]) {
 84         num -= siz[p];
 85         p = nxt[p];
 86     }
 87     split(p,num);
 88     p = nxt[p];
 89     for (int i=nxt[cur]; i!=p; i=nxt[cur]) {
 90         nxt[cur] = nxt[i];
 91         Delnum(i);
 92     }
 93     Maintain();
 94 } 
 95 void Getdata(int pos,int num,char str[]) {
 96     int cur = find(pos);
 97     int cnt = siz[cur] - pos;
 98     if (num < cnt) cnt = num;
 99     memcpy(str,data[cur]+pos,cnt);
100     int tmp = nxt[cur];
101     while (tmp!=-1 && cnt+siz[tmp] <= num) {
102         memcpy(str+cnt,data[tmp],siz[tmp]);
103         cnt += siz[tmp];
104         tmp = nxt[tmp];
105     }
106     if (num - cnt && tmp != -1) 
107         memcpy(str+cnt,data[tmp],num-cnt);
108     str[num] = '\0';
109 } 
110 int main() {
111     Init();
112     int Nowpos = 0,opt,num;
113     scanf("%d",&opt);
114     while (opt) {
115         opt--;
116         scanf("%s",s);
117         if (s[0]=='M') scanf("%d",&Nowpos);
118         else if (s[0]=='I')    {
119             scanf("%d",&num);
120             for (int i=0; i<num; ++i) {
121                 scanf("%c",&str[i]);
122                 if (str[i]<32 || str[i]>126) --i;
123             }
124             Insert(Nowpos,num,str);    
125         }
126         else if (s[0]=='D') {
127             scanf("%d",&num);
128             Erase(Nowpos,num);
129         }
130         else if (s[0]=='G') {
131             scanf("%d",&num);
132             Getdata(Nowpos,num,str);
133             printf("%s\n",str);        
134         }
135         else if (s[0]=='P') --Nowpos;
136         else ++Nowpos;
137     }
138     return 0;
139 }

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:洛谷P3384 【模板】树链剖分

下一篇:单链表