bzoj1507: [NOI2003]Editor
区间型splay,需要很多种操作。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 4000000 + 10; struct Editor { int l[maxn],r[maxn],f[maxn],s[maxn]; char c[maxn]; int pos,root,cnt; void update(int u) { s[u] = s[l[u]] + s[r[u]] + 1; } void lr(int x) { int y = f[x]; r[y] = l[x]; if(l[x]) f[l[x]] = y; f[x] = f[y]; if(root == y) root = x; else if(l[f[y]] == y) l[f[y]] = x; else r[f[y]] = x; f[y] = x; l[x] = y; update(y); update(x); } void rr(int x) { int y = f[x]; l[y] = r[x]; if(r[x]) f[r[x]] = y; f[x] = f[y]; if(root == y) root = x; else if(l[f[y]] == y) l[f[y]] = x; else r[f[y]] = x; f[y] = x; r[x] = y; update(y); update(x); } void rotate(int x) { if(l[f[x]] == x) rr(x); else lr(x); } void splay(int x,int target) { while(f[x] != target) { if(f[f[x]] == target) rotate(x); else if ((l[f[f[x]]] == f[x]) == (l[f[x]] == x)) rotate(f[x]),rotate(x); else rotate(x),rotate(x); } } int find(int k) { int x = root; while(s[l[x]] + 1 != k) { if(s[l[x]]+1<k) { k -= s[l[x]] + 1; x = r[x]; } else x = l[x]; } return x; } void build(int &x,int L,int R) { if(L > R) return; x = ++cnt; build(l[x],L,((L+R)>>1)-1); while((c[x] = getchar()) == '\n'); build(r[x],((L+R)>>1)+1,R); if(l[x]) f[l[x]]=x; if(r[x]) f[r[x]]=x; update(x); } void print(int x) { if(!x) return; print(l[x]); putchar(c[x]); print(r[x]); } void move(int k) { pos = k; } void prev() { pos--; } void nextv() { pos++; } void insert(int n) { splay(find(pos+1),0); splay(find(pos+2),root); getchar(); build(l[r[root]],1,n); f[l[r[root]]] = r[root]; update(r[root]); update(root); } void Delete(int n) { splay(find(pos+1),0); splay(find(pos+n+2),root); l[r[root]] = 0; update(r[root]); update(root); } void get(int n) { splay(find(pos+1),0); splay(find(pos+n+2),root); print(l[r[root]]); putchar('\n'); } void init() { f[2] = 1; r[1] = 2; s[2] = 1; s[1] = 2; c[1] = '['; c[2] = ']'; pos = 0,root = 1,cnt = 2; } } editor; char op[20]; int T,k; int main() { editor.init(); scanf("%d",&T); for(int i = 1; i <= T; i++) { scanf("%s",op); if(op[0] == 'M') { scanf("%d",&k); editor.move(k); } else if(op[0] == 'I') { scanf("%d",&k); editor.insert(k); } else if(op[0] == 'D') { scanf("%d",&k); editor.Delete(k); } else if(op[0] == 'G') { scanf("%d",&k); editor.get(k); } else if(op[0] == 'P') editor.prev(); else editor.nextv(); } return 0; }