BZOJ1507 [NOI2003]Editor 【splay】
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; }