1507: [NOI2003]Editor
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4129 Solved: 1660
[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
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
abcde^_^f.\/.ghijklmno
和之前写过的一道省选题几乎一样【少了个翻转,简单些】
splay水过
【附上TLE,MLE,RE,WA,AC崩溃路程QAQ】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define isr(u) (e[e[u].f].ch[1] == u)
#define ls e[u].ch[0]
#define rs e[u].ch[1]
#define sizl(u) (e[e[u].ch[0]].siz)
using namespace std;
const int maxn = 1000005,maxm = 3000005,INF = 1000000000;
inline int RD(){int out = 0,flag = 1; char c = getchar();while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}return out * flag;
}
char cmd[105],s[maxm];
int siz = 0,pos = 0,rt = 0;
struct node{char c; int ch[2],f,siz;}e[maxm];
inline void pup(int u) {e[u].siz = sizl(u) + 1 + e[rs].siz;}
inline void spin(int u){int s = isr(u),fa = e[u].f;e[u].f = e[fa].f; if (e[fa].f) e[e[fa].f].ch[isr(fa)] = u;e[fa].ch[s] = e[u].ch[s ^ 1]; if (e[u].ch[s ^ 1]) e[e[u].ch[s ^ 1]].f = fa;e[fa].f = u; e[u].ch[s ^ 1] = fa;pup(fa); pup(u);
}
inline void splay(int u,int v = 0){for (; e[u].f != v; spin(u))if (e[e[u].f].f != v) spin((isr(u) ^ isr(e[u].f)) ? u : e[u].f);if (!v) rt = u;
}
inline void Kth(int k,int p){int u = rt;while (true){if (sizl(u) >= k) u = ls;else if (sizl(u) + 1 == k) {splay(u,p);break;}else k -= sizl(u) + 1,u = rs;}
}
int build(int fa,int l,int r){if (l > r) return 0;int u = ++siz; e[u].f = fa; e[u].siz = 1;int mid = l + r >> 1; e[u].c = s[mid];if (l == r) return u;e[u].ch[0] = build(u,l,mid - 1);e[u].ch[1] = build(u,mid + 1,r);pup(u);return u;
}
void Insert(){int n = RD(); char c;Kth(pos + 1,0); Kth(pos + 2,rt);for (int i = 1; i <= n; i++){c = getchar(); while (c < 32 || c > 126) c = getchar(); s[i] = c;}e[e[rt].ch[1]].ch[0] = build(e[rt].ch[1],1,n);pup(e[rt].ch[1]); pup(rt);
}
void Print(int u){if (!u) return;Print(ls); printf("%c",e[u].c); Print(rs);
}
void Delete(){int n = RD();Kth(pos + 1,0); Kth(pos + n + 2,rt);e[e[rt].ch[1]].ch[0] = 0;pup(e[rt].ch[1]); pup(rt);
}
void Get(){int n = RD();Kth(pos + 1,0); Kth(pos + n + 2,rt);Print(e[e[rt].ch[1]].ch[0]); printf("\n");
}
int main(){//freopen("out.txt","w",stdout);e[siz = 2].f = 1; e[rt = 1].ch[1] = siz; e[rt].siz = 2; e[siz].siz = 1;int T = RD();while (T--){scanf("%s",cmd);switch(cmd[0]){case 'M':pos = RD();break;case 'I':Insert();break;case 'D':Delete();break;case 'G':Get();break;case 'P':pos--;break;case 'N':pos++;break;default:break;}}return 0;
}