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;
}
posted @ 2016-04-13 22:52  invoid  阅读(130)  评论(0编辑  收藏  举报