zoukankan      html  css  js  c++  java
  • 【数据结构】无旋Treap

    维护翻转操作

    struct Treap {
    
    private:
    
        static const int MAXN = 200000 + 10;
        int ls[MAXN], rs[MAXN];
        int rnd[MAXN], siz[MAXN];
        int del[MAXN], dnt;
        int cnt, root;
    
        int val[MAXN];
        ll sum[MAXN];
    
        bool rev[MAXN];
    
        int NewNode(int v) {
            int o = dnt ? del[dnt--] : ++cnt;
            ls[o] = 0, rs[o] = 0;
            rnd[o] = rand(), siz[o] = 1;
            val[o] = v, sum[o] = (ll)v;
            rev[o] = 0;
            return o;
        }
    
        void PushUp(int o) {
            siz[o] = siz[ls[o]] + siz[rs[o]] + 1;
            sum[o] = sum[ls[o]] + sum[rs[o]] + val[o];
        }
    
        void PushDown(int o) {
            if(rev[o]) {
                swap(ls[o], rs[o]);
                rev[ls[o]] ^= 1;
                rev[rs[o]] ^= 1;
                rev[o] = 0;
            }
        }
    
        void SplitRank(int o, int rnk, int &x, int &y) {
            if(!o) {
                x = 0, y = 0;
                return;
            }
            PushDown(o);
            if(rnk <= siz[ls[o]]) {
                y = o;
                SplitRank(ls[o], rnk, x, ls[o]);
                PushUp(y);
            } else {
                x = o;
                SplitRank(rs[o], rnk - siz[ls[o]] - 1, rs[o], y);
                PushUp(x);
            }
        }
    
        int Merge(int x, int y) {
            if(!x || !y)
                return x | y;
            PushDown(x), PushDown(y);
            if(rnd[x] < rnd[y]) {
                rs[x] = Merge(rs[x], y);
                PushUp(x);
                return x;
            } else {
                ls[y] = Merge(x, ls[y]);
                PushUp(y);
                return y;
            }
        }
    
    public:
    
        void Clear() {
            dnt = 0, cnt = 0;
            root = NewNode(0);
            siz[root] = 0;
        }
    
        void Insert(int rnk, int v) {
            int L1 = 0, R1 = 0;
            SplitRank(root, rnk - 1, L1, R1);
            L1 = Merge(L1, NewNode(v));
            root = Merge(L1, R1);
        }
    
        void Erase(int rnk) {
            int L1 = 0, R1 = 0;
            SplitRank(root, rnk - 1, L1, R1);
            int L2 = 0, R2 = 0;
            SplitRank(R1, 1, L2, R2);
            R1 = R2, del[++dnt] = L2;
            root = Merge(L1, R1);
        }
    
        int Value(int rnk) {
            int L1 = 0, R1 = 0;
            SplitRank(root, rnk - 1, L1, R1);
            int L2 = 0, R2 = 0;
            SplitRank(R1, 1, L2, R2);
            int res = val[L2];
            R1 = Merge(L2, R2);
            root = Merge(L1, R1);
            return res;
        }
    
        void Reverse(int l, int r) {
            int L1 = 0, R1 = 0;
            SplitRank(root, l - 1, L1, R1);
            int L2 = 0, R2 = 0;
            SplitRank(R1, r - l + 1, L2, R2);
            rev[L2] ^= 1;
            R1 = Merge(L2, R2);
            root = Merge(L1, R1);
        }
    
    } treap;
    

    无旋Treap,常用于维护序列,虽然Splay也可以做。
    最大优势:在线,时空复杂度基于元素数量,可以可持久化

    与离线离散化的权值线段树相比:在线
    与动态开点的权值线段树/01Trie相比:时空复杂度基于元素数量,相对更节省,且写起来简单
    与其他平衡树相比:可以可持久化

    综上所述,这是一个非常优秀的数据结构,其不可替代性非常强

  • 相关阅读:
    C# winform中读取HTML代码
    C#获取参数getParameter
    C# checkboxlist的使用
    win7任务栏只显示日期不显示年月日
    做事要仔细
    JSP显示不完全问题
    C# tabconctrol切换事件
    C#中combobox不可编辑与不可选择
    根据单选框改变的文本框
    JS判断form内所有表单是否为空
  • 原文地址:https://www.cnblogs.com/purinliang/p/13665834.html
Copyright © 2011-2022 走看看