zoukankan      html  css  js  c++  java
  • HDU 6087 Rikka with Sequence 可持久化treap (看题解)

    HDU 6087 

    学习了一手可持久化treap

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    
    int n, m, init, root, top, v[N];
    
    struct Treap {
    #define l(u) a[u].ch[0]
    #define r(u) a[u].ch[1]
        struct Node {
            int ch[2];
            int val, sz;
            LL sum;
        };
    
        int tot;
        Node a[2750000];
    
        inline int NewNode(int x) {
            tot++;
            a[tot].ch[0] = a[tot].ch[1] = 0;
            a[tot].val = a[tot].sum = x; a[tot].sz = 1;
            return tot;
        }
    
        inline int CpyNode(int id) {
            tot++;
            a[tot] = a[id];
            return tot;
        }
    
        inline void pull(int u) {
            a[u].sz = a[l(u)].sz + a[r(u)].sz + 1;
            a[u].sum = a[l(u)].sum + a[r(u)].sum + a[u].val;
        }
    
        void Split(int w, int k, int &u, int &v) {
            if(!w) {
                u = v = 0;
                return;
            }
            if(k >= a[l(w)].sz + 1) {
                u = CpyNode(w);
                Split(r(w), k - a[l(w)].sz - 1, r(u), v);
                pull(u);
            } else {
                v = CpyNode(w);
                Split(l(w), k, u, l(v));
                pull(v);
            }
        }
    
        void Merge(int &w, int u, int v) {
            if(!u || !v) {
                w = u | v;
                return;
            }
            if(rng() % (a[u].sz + a[v].sz) < a[u].sz) {
                w = CpyNode(u);
                Merge(r(w), r(u), v);
            } else {
                w = CpyNode(v);
                Merge(l(w), u, l(v));
            }
            pull(w);
        }
    
        LL query(int &u, int l, int r) {
            int L, M, R;
            Split(u, r, L, R);
            Split(L, l - 1, L, M);
            LL ret = a[M].sum;
            Merge(L, L, M);
            Merge(u, L, R);
            return ret;
        }
    
        void update1(int &u, int l, int r, int k) {
            int L1, R1, M1, L2, R2, M2;
    
            Split(u, l - 1, L1, R1);
            Split(L1, l - k - 1, L1, M1);
    
            Split(u, r, L2, R2);
            Split(L2, l - 1, L2, M2);
    
            while(a[M1].sz < r - l + 1) Merge(M1, M1, M1);
    
            Split(M1, r - l + 1, M1, M2);
    
            Merge(L2, L2, M1);
            Merge(u, L2, R2);
        }
    
        void update2(int &u, int v, int l, int r) {
            int L1, M1, R1, L2, M2, R2;
    
            Split(u, r, L1, R1);
            Split(L1, l - 1, L1, M1);
    
            Split(v, r, L2, R2);
            Split(L2, l - 1, L2, M2);
    
            Merge(L1, L1, M2);
            Merge(u, L1, R1);
        }
    
        void build(int &u, int l, int r) {
            if(l > r) {
                u = 0;
                return;
            }
            int mid = l + r >> 1;
            u = NewNode(v[mid]);
            build(l(u), l, mid - 1);
            build(r(u), mid + 1, r);
            pull(u);
        }
    
        void dfs(int u) {
            if(!u) return;
            dfs(l(u));
            v[++top] = a[u].val;
            dfs(r(u));
        }
    
        void ReBuild() {
            tot = a[init].sz;
            top = 0;
            dfs(root);
            build(root, 1, n);
        }
    } treap;
    
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &v[i]);
        }
    
        treap.build(init, 1, n);
        root = init;
    
        int op, l, r, k;
    
        while(m--) {
            scanf("%d%d%d", &op, &l, &r);
    
            if(op == 1) {
                printf("%lld
    ", treap.query(root, l, r));
            } else if(op == 2) {
                scanf("%d", &k);
                treap.update1(root, l, r, k);
            } else {
                treap.update2(root, init, l, r);
            }
    
            if(treap.tot >= 2500000) {
                treap.ReBuild();
            }
        }
        return 0;
    }
    
    /*
    */

    板子

    struct Treap {
    #define l(u) a[u].ch[0]
    #define r(u) a[u].ch[1]
        struct Node {
            int ch[2];
            int mx, val, sz;
        };
    
        int tot;
        Node a[N * 25];
    
        inline int NewNode(int x) {
            tot++;
            a[tot].ch[0] = a[tot].ch[1] = 0;
            a[tot].val = a[tot].mx = x; a[tot].sz = 1;
            return tot;
        }
    
        inline int CpyNode(int id) {
            tot++;
            a[tot] = a[id];
            return tot;
        }
    
        inline void pull(int u) {
            a[u].sz = a[l(u)].sz + a[r(u)].sz + 1;
            a[u].mx = max(a[u].val, max(a[l(u)].mx, a[r(u)].mx));
        }
    
        void Split(int w, int k, int &u, int &v, int op) {  // 分出前k小
            if(!w) {
                u = v = 0;
                return;
            }
            if(k >= a[l(w)].sz + 1) {
                u = op ? CpyNode(w) : w;
                Split(r(w), k - a[l(w)].sz - 1, r(u), v, op);
                pull(u);
            } else {
                v = op ? CpyNode(w) : w;
                Split(l(w), k, u, l(v), op);
                pull(v);
            }
        }
    
        void Merge(int &w, int u, int v, int op) { //合并u, v两个子树到w
            if(!u || !v) {
                w = u | v;
                return;
            }
            if(rng() % (a[u].sz + a[v].sz) < a[u].sz) {
                w = op ? CpyNode(u) : u;
                Merge(r(w), r(u), v, op);
            } else {
                w = op ? CpyNode(v) : v;
                Merge(l(w), u, l(v), op);
            }
            pull(w);
        }
    
        int queryKth(int w, int k){
            if(a[l(w)].sz >= k) return queryKth(l(w), k);
            else k -= a[l(w)].sz;
            if(k == 1) return a[w].val;
            k -= 1;
            return queryKth(r(w), k);
        }
    
        void build(int &u, int l, int r) {
            if(l > r) {
                u = 0;
                return;
            }
            int mid = l + r >> 1;
            u = NewNode(v[mid]);
            build(l(u), l, mid - 1);
            build(r(u), mid + 1, r);
            pull(u);
        }
    } treap;
  • 相关阅读:
    CentOS 5.5和5.6 安装后的网络配置
    CentOS 5.5 系统安全配置
    printk: messages suppressed
    “找不到出路的”vb6.0
    用户控件的烦扰
    rman恢复
    oracle数据字典
    oracle自关联表的子删父变功能实现
    oracle自治事务
    oracle表空间更名
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11110420.html
Copyright © 2011-2022 走看看