【模板】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;
}

转载于:https://www.cnblogs.com/akakw1/p/9915834.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值