• 模板汇总——treap


    1. 旋转treap。

    思想:一颗权值BST + 一颗 随机数 最小堆。

    BZOJ - 3224

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    #define inf 300000030
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    struct Treap{
        int L[N], R[N], sz[N], v[N], rnd[N], ct[N], tot, root;
        void init(){
            tot = root = 0;
        }
        inline int rand(){
            static int seed = 12345;
            return seed = (int)seed * 482711LL % 2147483647;
        }
        void Updata(int p){
            sz[p] = ct[p] + sz[L[p]] + sz[R[p]];
        }
        void turnL(int &k){
            int t = R[k];
            R[k] = L[t];
            L[t] = k;
            sz[t] = sz[k];
            Updata(k);
            k = t;
        }
        void turnR(int &k){
            int t = L[k];
            L[k] = R[t];
            R[t] = k;
            sz[t] = sz[k];
            Updata(k);
            k = t;
        }
        void Insert(int &p, int x){
            if(!p){
                p = ++tot;
                sz[p] = ct[p] = 1;
                v[p] = x; rnd[p] = rand();
                return ;
            }
            sz[p]++;
            if(v[p] == x) ct[p]++;
            else if(x > v[p]){
                Insert(R[p], x);
                if(rnd[R[p]] < rnd[p]) turnL(p);
            }
            else {
                Insert(L[p], x);
                if(rnd[L[p]] < rnd[p]) turnR(p);
            }
        }
        void Delete(int &p, int x){
            if(!p) return ;
            if(v[p] == x){
                if(ct[p] > 1) ct[p]--, sz[p]--;
                else {
                    if(L[p] == 0 || R[p] == 0) p = L[p] + R[p];
                    else if(rnd[L[p]] < rnd[R[p]]) turnR(p), Delete(p, x);
                    else turnL(p), Delete(p, x);
                }
            }
            else if(x > v[p]) sz[p]--, Delete(R[p], x);
            else sz[p]--, Delete(L[p], x);
        }
        int Query_Rank_of_x(int p, int x){
            if(!p) return 0;
            if(v[p] == x) return sz[L[p]]+1;
            if(v[p] > x) return Query_Rank_of_x(L[p], x);
            return ct[p] + sz[L[p]] + Query_Rank_of_x(R[p], x);
        }
        int Query_kth(int p, int k){
            if(!p) return -1;
            if(sz[L[p]] >= k) return Query_kth(L[p], k);
            k -= sz[L[p]];
            if(k <= ct[p]) return v[p];
            k -= ct[p];
            return Query_kth(R[p], k);
        }
        int FindFront(int p, int x){
            if(!p) return -inf;
            if(v[p] < x) return max(v[p], FindFront(R[p], x));
            return FindFront(L[p], x);
        }
        int FindNext(int p, int x){
            if(!p) return inf;
            if(v[p] <= x) return FindNext(R[p], x);
            return min(v[p], FindNext(L[p], x));
        }
    }treap;
    int main(){
        int T;
        int op, x;
        scanf("%d", &T);
        treap.init();
        while(T--){
            scanf("%d%d", &op, &x);
            if(op == 1) treap.Insert(treap.root, x);
            else if(op == 2) treap.Delete(treap.root, x);
            else if(op == 3) printf("%d
    ", treap.Query_Rank_of_x(treap.root, x));
            else if(op == 4) printf("%d
    ", treap.Query_kth(treap.root, x));
            else if(op == 5) printf("%d
    ", treap.FindFront(treap.root, x));
            else if(op == 6) printf("%d
    ", treap.FindNext(treap.root, x));
        }
        return 0;
    }
    View Code

    2.无旋 + 可持久化Treap

    HDU - 6087

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 3e6;
    const int M = 2e5 + 100;
    int a[M], top;
    int n, m;
    struct Treap{
        int L[N], R[N], sz[N], v[N], tot, root, prt;
        LL sum[N];
        inline void init(){
            prt = root = tot = 0;
        }
        inline void PushUp(int x){
            sz[x] = 1 + sz[L[x]] + sz[R[x]];
            sum[x] = v[x] + sum[L[x]] + sum[R[x]];
        }
        inline int NowNode(int val){
            ++tot;
            L[tot] = R[tot] = 0; sz[tot] = 1;
            v[tot] = sum[tot] = val;
            return tot;
        }
        inline int CopyNode(int pre){
            ++tot;
            L[tot] = L[pre]; R[tot] = R[pre]; sz[tot] = sz[pre];
            v[tot] = v[pre]; sum[tot] = sum[pre];
            return tot;
        }
        pll Split(int x, int k){
            if(!x) return pll(0, 0);
            pll y;
            x = CopyNode(x);
            if(sz[L[x]] >= k){
                y = Split(L[x], k);
                L[x] = y.se;
                PushUp(x);
                y.se = x;
            }
            else {
                y = Split(R[x], k-sz[L[x]]-1);
                R[x] = y.fi;
                PushUp(x);
                y.fi = x;
            }
            return y;
        }
        int Merge(int x, int y){
            if(!x || !y) return x | y;
            if(rand() % (sz[x] + sz[y]) <= sz[x]){
                x = CopyNode(x);
                R[x] = Merge(R[x], y);
                PushUp(x);
                return x;
            }
            else {
                y = CopyNode(y);
                L[y] = Merge(x, L[y]);
                PushUp(y);
                return y;
            }
        }
        LL Query_kth_sum(int x, int k){
            if(!x || !k) return 0;
            if(sz[L[x]] >= k) return Query_kth_sum(L[x], k);
            return Query_kth_sum(R[x], k-sz[L[x]]-1) + sum[L[x]] + v[x];
        }
        LL Querysum(int l, int r){
            return Query_kth_sum(root, r) - Query_kth_sum(root, l-1);
        }
        void Updata1(int l, int r, int k){
            ///   ... l-k ... l .... r .... n
            pll p1 = Split(root, r);
            pll p2 = Split(p1.fi, l-1);
            pll p3 = Split(p2.fi, l-k-1);
            int zzz = p3.se;
            while(sz[zzz] < r - l + 1) zzz = Merge(zzz, zzz);
            pll p4 = Split(zzz, r-l+1);
            root = Merge(p2.fi, p4.fi);
            root = Merge(root, p1.se);
        }
        void Updata2(int l, int r){
            pll p1 = Split(prt, r);
            p1 = Split(p1.fi, l-1);
            pll p2 = Split(root, r);
            pll p3 = Split(p2.fi, l-1);
            root = Merge(p3.fi, p1.se);
            root = Merge(root, p2.se);
        }
        void Build(int & x, int l, int r){
            if(l > r) {x = 0; return;}
            int m = l+r >> 1;
            x = NowNode(a[m]);
            Build(L[x], l, m-1);
            Build(R[x], m+1, r);
            PushUp(x);
        }
        void dfs(int x){
            if(!x) return ;
            dfs(L[x]);
            a[++top] = v[x];
            dfs(R[x]);
        }
        void ReBuild(){
            tot = sz[prt];
            top = 0;
            dfs(root);
            Build(root, 1, n);
        }
    }treap;
    int main(){
        treap.init();
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i)
            scanf("%d", &a[i]);
        treap.Build(treap.root, 1, n);
        treap.prt = treap.root;
        int MaxP = 2e6 + 5e5;
        int op, l, r, k;
        for(int i = 1; i <= m; ++i){
            scanf("%d", &op);
            if(op == 1) {
                scanf("%d%d", &l, &r);
                printf("%lld
    ", treap.Querysum(l, r));
            }
            else if(op == 2){
                scanf("%d%d%d", &l, &r, &k);
                treap.Updata1(l, r, k);
            }
            else {
                scanf("%d%d", &l, &r);
                treap.Updata2(l, r);
            }
            if(treap.tot > MaxP){
                treap.ReBuild();
            }
        }
        return 0;
    }
    View Code

    3.普通treap

    19牛客多校4F

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    int n, m;
    struct Treap{
        int L[N], R[N], sz[N], v[N], tot, root, prt, key[N];
        int Max[N];
        inline void init(){
            root = tot = 0;
        }
        inline void PushUp(int x){
            sz[x] = 1 + sz[L[x]] + sz[R[x]];
            Max[x] = max({v[x], Max[L[x]], Max[R[x]]});
        }
        void Split(int x, int k, int &l, int &r){
            if(!x) {l = r = 0; return ;}
            if(sz[L[x]] >= k){
                r = x;
                Split(L[x], k, l, L[x]);
            }
            else {
                l = x;
                Split(R[x], k-sz[L[x]]-1, R[x], r);
            }
            if(l) PushUp(l);
            if(r) PushUp(r);
        }
        int Merge(int x, int y){
            if(!x || !y) return x | y;
            if(key[x] > key[y]){
                R[x] = Merge(R[x], y);
                PushUp(x);
                return x;
            }
            else {
                L[y] = Merge(x, L[y]);
                PushUp(y);
                return y;
            }
        }
        inline void NowNode(int val){
            ++tot;
            L[tot] = R[tot] = 0; sz[tot] = 1;
            v[tot] = Max[tot] = val;
            key[tot] = rand();
            root = Merge(root, tot);
        }
        int Query_kth(int x, int k){
            if(sz[L[x]] >= k) return Query_kth(L[x], k);
            else k -= sz[L[x]];
            if(k == 1) return v[x];
            k -= 1;
            return Query_kth(R[x], k);
        }
        int get_lens(int x, int val){
            if(!x) return 0;
            if(Max[L[x]] > val) return get_lens(L[x], val);
            if(v[x] > val) return sz[L[x]];
            return sz[L[x]] + 1 + get_lens(R[x], val);
        }
        void solve(){
            int l, m, r;
            scanf("%d%d%d", &l, &m, &r);
            int t1, t2, t3;
            Split(root, r, t1, t2);
            root = t1;
            Split(root, m, t1, t3);
            root = 0;
            while(t1 && t3){
                int A = Query_kth(t1, 1), B = Query_kth(t3, 1);
                if(A > B) {
                    swap(A, B);
                    swap(t1, t3);
                }
                int len = get_lens(t1, B), tmp;
                Split(t1, len, tmp, t1);
                root = Merge(root, tmp);
            }
            if(t1) root = Merge(root, t1);
            if(t3) root = Merge(root, t3);
            root = Merge(root, t2);
        }
    }treap;
    int main(){
        treap.init();
        srand(time(0));
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i){
            int v;
            scanf("%d", &v);
            treap.NowNode(v);
        }
        int op;
        for(int i = 1; i <= m; ++i){
            scanf("%d", &op);
            if(op == 1)
                treap.solve();
            else {
                scanf("%d", &op);
                printf("%d
    ", treap.Query_kth(treap.root, op));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    .NET程序员 湖南创世纪网络
    java.lang.NoSuchMethodError:SpringJAR包版本冲突错误解决方法
    事实表和纬度表概述
    SQL Server中char、nchar、varchar、nvarchar的区别
    biztalk 2010 映射
    biztalk 2010 架构
    字符编码简单总结
    浅析组织结构与个人发展的关系
    缓慢渐变维度的处理方式
    SQL server中SET ANSI_PADDING对char、varchar、nvarchar的影响
  • 原文地址:https://www.cnblogs.com/MingSD/p/11142438.html
Copyright © 2020-2023  润新知