1. 程式人生 > >【模板】Splay(區間操作)

【模板】Splay(區間操作)

這裡的操作是區間翻轉

struct node* null;//注意這個要在主函式中初始化
struct node {
    node *son[2], *fa;
    int v;
    int s;
    bool tag;
    node() {
        son[0] = son[1] = fa = null;
        tag = 0;
    }
    void push_up() {
        s = son[0]->s + son[1]->s + 1;
    }
    void push_down() {
        if(tag) {
            swap(son[0], son[1]);
            son[0]->tag ^= 1;
            son[1]->tag ^= 1;
            tag = false;
        }
    }
}*root;
void rotate(node *p) {
    p->push_down();
    node *f = p->fa;
    node *ff = f->fa;
    ff->son[f == ff->son[1]] = p;
    p->fa = ff;
    bool c = p == f->son[1];
    f->son[c] = p->son[!c];
    p->son[!c]->fa = f;
    f->fa = p;
    p->son[!c] = f;
    p->push_up(), f->push_up();
}
void splay(node *p, node *r = null) {
    node *f = p->fa, *ff;
    while(f != r) {
        ff = f->fa;
        if(ff != r) {
            if((p == f->son[1]) ^ (f == ff->son[1]))rotate(p);
            else rotate(f);
        }
        rotate(p);
        f = p->fa;
    }
    if(r == null)root = p;
}
void build(int n) {
    root = new node;
    root->v = 0;
    node* p =root;
    for(int i = 1; i <= n + 1; i ++)
        p->son[1] = new node, p->son[1]->fa = p, p = p->son[1], p->v = i;
    p->s = 1;
    splay(p);
}
node* kth(int k) {
    node *p = root;
    while(1) {
        p->push_down();
        if(p->son[0]->s >= k)p = p->son[0];
        else if(p->son[0]->s + 1 ==k)return p;
        else k -= p->son[0]->s + 1, p = p->son[1];
    }
}
void work(int l, int r) {
    splay(kth(l));
    splay(kth(r + 2), root);
    root->son[1]->son[0]->tag ^= 1;
}