• Luogu P3391 【模板】文艺平衡树(FHQ-Treap)


    题意

    给出一个长为$n$序列$[1,2,...,n]$,$m$次操作,每次指定一段区间$[l,r]$,将这段区间翻转,求最终序列

    题解

    虽然标题是$Splay$,但是我要用$FHQ Treap$,考虑先将$[l,r]$这段区间$split$出来($k$即为这段区间)

    void split(int o, int k, int &l, int &r) {
        if(!o) { l = r = 0; return ; }
        if(siz[lc[o]] < k) l = o, split(rc[o], k - siz[lc[o]] - 1, rc[o], r);
        else r = o, split(lc[o], k, l, lc[o]);
        upt(o);
    }//注意这里要按size来split
    
    //写在main函数中
    while(m--) {
        read(x), read(y);
        split(rt, y, l, r), split(l, x - 1, l, k);
        rev[k] ^= 1; rt = merge(merge(l, k), r);
    }//x,y为操作的区间
    

    然后再将这段区间打一个翻转标记(因为平衡树是可以中序遍历输出的吧...,$rev$为翻转标记)

    每次涉及到某个节点时,将$rev$标记下放就好了

    void pushdown(int o) {
        std::swap(lc[o], rc[o]);
        if(lc[o]) rev[lc[o]] ^= 1;
        if(rc[o]) rev[rc[o]] ^= 1;
        rev[o] = 0;
    }
    

    #include <ctime>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    
    template<typename T>
    void read(T &x) {
        int flag = 1; x = 0; char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
        while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
    }
    
    const int N = 1e5 + 10;
    int n, m, lc[N], rc[N], siz[N], val[N], pri[N], rev[N], tot;
    
    inline void upt(int o) { siz[o] = siz[lc[o]] + siz[rc[o]] + 1; }
    inline int node(int x) { val[++tot] = x, pri[tot] = rand(), siz[tot] = 1; return tot;}
    void pushdown(int o) {
        std::swap(lc[o], rc[o]);
        if(lc[o]) rev[lc[o]] ^= 1;
        if(rc[o]) rev[rc[o]] ^= 1;
        rev[o] = 0;
    }
    void split(int o, int k, int &l, int &r) {
        if(!o) { l = r = 0; return ; }
        if(rev[o]) pushdown(o);
        if(siz[lc[o]] < k) l = o, split(rc[o], k - siz[lc[o]] - 1, rc[o], r);
        else r = o, split(lc[o], k, l, lc[o]);
        upt(o);
    }
    int merge(int l, int r) {
        if(!l || !r) return l + r;
        if(pri[l] < pri[r]) { if(rev[l]) pushdown(l); rc[l] = merge(rc[l], r), upt(l); return l; }
        else { if(rev[r]) pushdown(r); lc[r] = merge(l, lc[r]), upt(r); return r; }
    }
    void print(int o) {
        if(!o) return ;
        if(rev[o]) pushdown(o);
        print(lc[o]), printf("%d ", val[o]), print(rc[o]);
    }
    
    int main () {
        read(n), read(m), srand((unsigned)time(NULL));
        int x, y, l, r, k, rt = 0;
        for(int i = 1; i <= n; ++i) rt = merge(rt, node(i));
        while(m--) {
            read(x), read(y);
            split(rt, y, l, r), split(l, x - 1, l, k);
            rev[k] ^= 1; rt = merge(merge(l, k), r);
        } print(rt);
        return 0;
    }
    
  • 相关阅读:
    NetCore物联网平台 4
    NetCore物联网平台 3
    NetCore物联网平台 2
    NetCore物联网平台 1
    阿里云IoT 8:待更新
    阿里云IoT 7:待更新
    阿里云IoT 6:待更新
    阿里云IoT 5:待更新
    阿里云IoT 4:数据解析
    svg 实现半环形进度条
  • 原文地址:https://www.cnblogs.com/water-mi/p/10159803.html
Copyright © 2020-2023  润新知