• 【LG5055】可持久化文艺平衡树


    【LG5055】可持久化文艺平衡树

    题面

    洛谷

    题解

    终于不可以用(Trie)水了。。。

    和普通的(FHQ;treap)差不多

    注意一下(pushdown)(split)要新开节点

    代码

    #include <iostream> 
    #include <cstdio> 
    #include <cstdlib> 
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    #include <ctime> 
    using namespace std; 
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (!isdigit(ch) && ch != '-') ch = getchar(); 
        if (ch == '-') w = -1, ch = getchar();
        while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
        return w * data; 
    }
    const int MAX_N = 2e5 + 5; 
    struct Node {
        int ls, rs, pri, val, size; 
        long long sum; 
        bool rev; 
    } t[MAX_N << 6]; 
    int rub[MAX_N << 6], cur, rubtop, rt[MAX_N];
    inline int newNode(int v = 0) { 
        int o = rubtop ? rub[rubtop--] : ++cur; 
        t[o].val = t[o].sum = v; t[o].pri = rand(); t[o].size = 1; 
        t[o].ls = t[o].rs = t[o].rev = 0; 
        return o; 
    }
    inline int clone(int y) { 
        int x = rubtop ? rub[rubtop--] : ++cur; 
        t[x] = t[y]; 
        return x; 
    } 
    inline void pushup(int o) {
        t[o].size = t[t[o].ls].size + t[t[o].rs].size + 1; 
        t[o].sum = t[t[o].ls].sum + t[t[o].rs].sum + t[o].val; 
    } 
    inline void pushdown(int o) {
        if (!t[o].rev) return ; 
        swap(t[o].ls, t[o].rs); 
        if (t[o].ls) t[o].ls = clone(t[o].ls), t[t[o].ls].rev ^= 1; 
        if (t[o].rs) t[o].rs = clone(t[o].rs), t[t[o].rs].rev ^= 1; 
        t[o].rev = 0; 
    } 
    void split(int o, int k, int &ls, int &rs) { 
        if (!o) ls = rs = 0; 
        else { 
            pushdown(o); 
            if (k <= t[t[o].ls].size) rs = clone(o), split(t[rs].ls, k, ls, t[rs].ls), pushup(rs); 
            else ls = clone(o), split(t[ls].rs, k - t[t[o].ls].size - 1, t[ls].rs, rs), pushup(ls); 
        } 
    } 
    int merge(int x, int y) { 
        if (!(x && y)) return x ^ y; 
        if (t[x].pri < t[y].pri) { 
            pushdown(y); 
            t[y].ls = merge(x, t[y].ls); 
            pushup(y); 
            return y; 
        } else {
            pushdown(x); 
            t[x].rs = merge(t[x].rs, y); 
            pushup(x);
            return x; 
        } 
    }
    void insert(int &o, int k, int v) { 
        int x, y; 
        split(o, k, x, y); 
        o = merge(merge(x, newNode(v)), y); 
    } 
    void erase(int &o, int pos) { 
        int x, y, z; 
        split(o, pos, x, z); 
        split(x, pos - 1, x, y);
        rub[++rubtop] = y; 
        o = merge(x, z); 
    }
    void reverse(int &o, int l, int r) { 
        int x, y, z; 
        split(o, r, x, z); 
        split(x, l - 1, x, y);
        t[y].rev ^= 1; 
        o = merge(merge(x, y), z); 
    } 
    long long query(int &o, int l, int r) { 
        int x, y, z; 
        split(o, r, x, z); 
        split(x, l - 1, x, y); 
        long long res = t[y].sum; 
        o = merge(merge(x, y), z);
        return res; 
    }
    long long ans = 0;
    int N; 
    int main () {
        srand(19260817); 
        N = gi(); 
        for (int i = 1; i <= N; i++) {
            int v = gi(), op = gi(); 
            rt[i] = rt[v]; 
            if (op == 1) { int k = gi() ^ ans, val = gi() ^ ans; insert(rt[i], k, val); }
            else if (op == 2) { int k = gi() ^ ans; erase(rt[i], k); } 
            else if (op == 3) { int l = gi() ^ ans, r = gi() ^ ans; reverse(rt[i], l, r); }
            else { int l = gi() ^ ans, r = gi() ^ ans; printf("%lld
    ", ans = query(rt[i], l, r)); }
        } 
        return 0; 
    } 
    
  • 相关阅读:
    DB2
    Data Queue
    QMQY
    CMD(SA400 Command)
    Software development process
    CSS display样式
    CSS行高line-height解释
    CS和CS3知识点
    HTML图片<img>标签空白解决方法
    CS清除浮动
  • 原文地址:https://www.cnblogs.com/heyujun/p/10199638.html
Copyright © 2020-2023  润新知