zoukankan      html  css  js  c++  java
  • 平衡树汇总

    一.Treap

    #include <bits/stdc++.h>
    using namespace std;
    const int SIZE = 100010;
    int INF = 0x7fffffff;
    
    int m, opt, x;
    int tot, root,  n;
    struct Treap
    {
        int l, r;
        int val, dat;
        int cnt, size; 
    }a[SIZE];
    
    int New(int val)
    {
        a[++tot].val = val;
        a[tot].dat = rand();
        a[tot].cnt = a[tot].size = 1;
        return tot;
    }
    
    void updata(int cur)
    {
        a[cur].size = a[a[cur].l].size + a[a[cur].r].size + a[cur].cnt;
    }
    
    void build()
    {
        New(-INF), New(INF);
        root = 1;
        a[1].r = 2;
        updata(root);
    }
    
    int GetRankByVal(int p, int val)
    {
        if(p == 0) return 0;
        if(val == a[p].val) return a[a[p].l].size + 1;
        if(val < a[p].val) return GetRankByVal(a[p].l, val);
        return GetRankByVal(a[p].r, val) + a[a[p].l].size + a[p].cnt;
    }
    
    int GetValByRank(int p, int rank)
    {
        if(p == 0) return INF;
        if(a[a[p].l].size >= rank) return GetValByRank(a[p].l, rank);
        if(a[a[p].l].size + a[p].cnt >= rank) return a[p].val ;
        return GetValByRank(a[p].r, rank - a[a[p].l].size - a[p].cnt);
    }
    
    void zig(int &p)
    {
        int q = a[p].l;
        a[p].l = a[q].r;
        a[q].r = p;
        p = q;
        updata(a[p].r), updata(p);
    }
    
    void zag(int &p)
    {
        int q = a[p].r;
        a[p].r = a[q].l;
        a[q].l = p;
        p = q;
        updata(a[p].l), updata(p);
    }
    
    void Insert(int &p, int val)
    {
        if(p == 0)
        {
            p = New(val);
            return;
        }
        if(val == a[p].val)
        {
            a[p].cnt++;
            updata(p);
            return;
        }
        if(val < a[p].val)
        {
            Insert(a[p].l, val);
            if(a[p].dat < a[a[p].l].dat) zig(p);
        }
        else 
        {
            Insert(a[p].r, val);
            if(a[p].dat < a[a[p].r].dat) zag(p);
        }
        updata(p);
    }
    
    int GetPre(int val)
    {
        int ans = 1;
        int p = root;
        while(p)
        {
            if(val == a[p].val)
            {
                if(a[p].l > 0)
                {
                    p = a[p].l;
                    while(a[p].r > 0) p = a[p].r;
                    ans = p;
                }
                break;
            }
            if(a[p].val < val && a[p].val > a[ans].val) ans = p;
            p = val < a[p].val ? a[p].l : a[p].r;
        }
        return a[ans].val;
    }
    
    int GetNext(int val)
    {
        int ans = 2;
        int p = root;
        while(p)
        {
            if(val == a[p].val)
            {
                if(a[p].r > 0)
                {
                    p = a[p].r;
                    while(a[p].l > 0) p = a[p].l;
                    ans = p;
                }
                break;
            }
            if(a[p].val > val && a[p].val < a[ans].val) ans = p;
            p = val < a[p].val ? a[p].l : a[p].r;
        }
        return a[ans].val;
    }
    
    void Remove(int &p, int val)
    {
        if(p == 0)return;
        if(val == a[p].val)
        {
            if(a[p].cnt > 1)
            {
                a[p].cnt--;
                updata(p);
                return;
            }
            if(a[p].l || a[p].r)
            {
                if(a[p].r == 0 || a[a[p].l].dat > a[a[p].r].dat)
                {
                    zig(p);
                    Remove(a[p].r, val);
                }
                else {
                    zag(p);
                    Remove(a[p].l, val);
                }
                updata(p);
            }
            else p = 0;
            return;
        }
        val < a[p].val ? Remove(a[p].l, val) : Remove(a[p].r, val);
        updata(p);
    }
    
    int main()
    {
        srand(time(0));
        build();
        cin>>m;
        while(m--)
        {
            scanf("%d%d",&opt,&x);
            switch(opt)
            {
                case 1:
                    Insert(root, x);
                    break;
                case 2:
                    Remove(root, x);
                    break;
                case 3:
                    printf("%d
    ",GetRankByVal(root, x) - 1);
                    break;
                case 4:
                    printf("%d
    ",GetValByRank(root, x + 1));
                    break;
                case 5:
                    printf("%d
    ",GetPre(x));
                    break;
                case 6:
                    printf("%d
    ",GetNext(x));
                    break;
            }
        }
        return 0;
        
    
        
    }
    zZhBr

    二.Splay

    #include <iostream>
    #include <cstdio> 
    #include <cstring>
    using namespace std;
    #define maxn 10000010
    #define inf 0x7f7f7f7f
    
    
    struct SplayTree
    {
        int ch[2], fa;
        int val, siz;
        int cnt;// 副本数 
    }t[maxn];
    
    int Root, tot;
    
    void pushup(int o)
    {
        t[o].siz = t[t[o].ch[0]].siz + t[t[o].ch[1]].siz + t[o].cnt;
    }
    
    void rotate(int x)
    {
        int y = t[x].fa, d = (t[y].ch[1] == x);
        t[ t[y].ch[d] = t[x].ch[d ^ 1] ].fa = y; // x 的儿子给 y ;   
        t[ t[x].fa = t[y].fa ].ch[ t[t[y].fa].ch[1] == y ] = x; // x 归为 y 的父亲的儿子 ; 
        t[ t[x].ch[d ^ 1] = y ].fa = x; // y 归为 x 的儿子; 
        pushup(y), pushup(x);
    }
    
    void Splay(int x, int f) // 把 x 旋转成 f 的儿子, 如果 f = 0, x 旋转到根节点: 
    {
        while(t[x].fa != f)
        {
            int y = t[x].fa, z = t[y].fa;
            if(z != f)
            {
                if ((t[z].ch[0] == y) == (t[y].ch[0] == x)) {
                rotate(y);
                } else {
                    rotate(x);
                }
                //rotate( (t[z].ch[0] == y) == (t[y].ch[0] == x) ? y : x);// x 与 y 为同一边子树 旋转 y, 否则旋转 x; 
            }
            rotate(x);
        }
        pushup(x);
        if(f == 0) Root = x;
    }
    
    void insert(int v)
    {
        int o = Root, u = 0;
        while(o && t[o].val != v)
        {
            u = o;
            int d = t[o].val < v;
            o = t[o].ch[d];
        }
        if(o)
        {
            t[o].cnt ++;
            pushup(o);
        }
        else
        {
            o = ++tot;
            if (u) 
            {
                int d = t[u].val < v;
                t[u].ch[d] = o;
            }
            t[o].fa = u;
            t[o].val = v;//cout<<t[o].val<<endl;
            t[o].siz = 1;
            t[o].cnt = 1;
            t[o].ch[1] = t[o].ch[0] = 0;
        }
        Splay(o, 0);
    }
    
    int K_th(int k)
    {
        int o = Root;
        if(t[o].siz < k)
        {
            return 0;
        }
        while(1)
        {
            if(k > t[t[o].ch[0]].siz + t[o].cnt)
            {
                k -= t[t[o].ch[0]].siz + t[o].cnt;
                o = t[o].ch[1];
            }
            else
            
                if(t[t[o].ch[0]].siz >= k)
                {
                    o = t[o].ch[0];
                }
                else
                {
                    break;
                }
            
        }
        Splay(o, 0);
        return t[o].val;
            
    }
    
    void Find(int x)
    {
        int o = Root;
        if(!o) return ;
    /*    while(1)
        {
            if(t[o].val == x)
            {
                Splay(o, 0);
                return ;
            }
            int d = t[o].val < x;
            if(!t[o].ch[o]) return ;
            o = t[o].ch[o];
        }*/
        while(t[o].ch[t[o].val < x] and x != t[o].val)
        {
            o = t[o].ch[t[o].val < x];
        }
        Splay(o, 0);
    }
    
    int Next(int x, int d)
    {
        Find(x);
        int o = Root;
        if( (t[o].val > x and d) or (t[o].val < x and !d)) return o;
        o = t[o].ch[d];
        while(t[o].ch[d ^ 1]) o = t[o].ch[d ^ 1];
        return o;
    }
    
    void Del(int x)
    {
        int lst = Next(x, 0);
        int nxt = Next(x, 1);
        Splay(lst, 0);Splay(nxt, lst);
        int del = t[nxt].ch[0];
        if(t[del].cnt > 1) 
        {
            t[del].cnt --;
            Splay(del, 0);
        }
        else t[nxt].ch[0] = 0;
    }
    
    int main()
    {
        insert(inf);
        insert(-inf);
        int n;
        cin >> n;
        while(n--)
        {
            int opt, x;
            scanf("%d%d", &opt, &x);
            if(opt == 1)
            {
                insert(x);
            }
            else if(opt == 2)
            {
                Del(x);
            }
            else if(opt == 3)
            {
                Find(x);
                printf("%d
    ", t[t[Root].ch[0]].siz);
            }
            else if(opt == 4)
            {
                printf("%d
    ", K_th(x + 1));
            }
            else if(opt == 5)
            {
                printf("%d
    ", t[Next(x, 0)].val);
            }
            else
            {
                printf("%d
    ", t[Next(x, 1)].val);
            }
        }
        return 0;    
    }
    zZhBr

     

    三.无旋Treap

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    #define maxn 500005
    
    struct FHQ_Treap
    {
        int ch[2];
        int val, pri;
        int siz, cnt;
    }t[maxn];
    
    int tot, Root;
    
    int newnode(int v)
    {
        tot++;
        t[tot].ch[1] = t[tot].ch[2] = 0;
        t[tot].cnt = t[tot].siz = 1;
        t[tot].val = v;
        t[tot].pri = rand();
        return tot;
    }
    
    void pushup(int o)
    {
        t[o].siz = t[t[o].ch[1]].siz + t[t[o].ch[0]].siz + t[o].cnt;
    }
    
    int Merge(int x, int y)
    {
        if(!x or !y) return x + y;
        if(t[x].pri < t[y].pri)
        {
            t[x].ch[1] = Merge(t[x].ch[1], y);
            pushup(x);
            return x;
        }
        else
        {
            t[y].ch[0] = Merge(x, t[y].ch[0]);
            pushup(y);
            return y;
        }
    }
    
    #define par pair<int, int>
    #define m_p make_pair
    #define fi first
    #define se second
    
    par Split1(int o, int k) // 按排名切 
    {
        if(!o or !k) return m_p(0, o);
        int d = t[t[o].ch[0]].siz;
        par res;
        if(k <= d)
        {
            res = Split1(t[o].ch[0], k);
            t[o].ch[0] = res.second;
            pushup(o);
            res.second = o;
        }
        else
        {
            res = Split1(t[o].ch[1], k - d - 1);
            t[o].ch[1] = res.first;
            pushup(o);
            res.first = o;
        }
        return res;
    }
    
    void Split2(int o, int k, int &x, int &y) // 按价值切
    {
        if(!o) x = y = 0;
        else
        {
            if(t[o].val <= k)
            {
                x = o;
                Split2(t[o].ch[1], k, t[o].ch[1], y);
            }
            else
            {
                y = o;
                Split2(t[o].ch[0], k, x, t[o].ch[0]);
            }
            pushup(o);
        }
    } 
    
    int K_th(int o, int k)
    {
        while(1)
        {
            if(k <= t[t[o].ch[0]].siz)
            {
                o = t[o].ch[0];
            }
            else if(k == t[t[o].ch[0]].siz + t[o].cnt)
            {
                return o;
            }
            else 
            {
                k -= t[t[o].ch[0]].siz + t[o].cnt;
                o = t[o].ch[1];
            }
        }
    }
    
    int main()
    {
        srand(time(0));
        int n;
        cin >> n;
        while(n--)
        {
            int opt, a;
            scanf("%d%d", &opt, &a);
            int x, y, z;
            if(opt == 1)
            {
                Split2(Root, a, x, y);
                Root = Merge(Merge(x, newnode(a)), y);
            }
            else if(opt == 2)
            {
                Split2(Root, a, x, z);
                Split2(x, a - 1, x, y);
                y = Merge(t[y].ch[0], t[y].ch[1]);
                Root = Merge(Merge(x, y), z);
            }
            else if(opt == 3)
            {
                Split2(Root, a - 1, x, y);
                printf("%d
    ", t[x].siz + t[x].cnt);
                Root = Merge(x, y);
            }
            else if(opt == 4)
            {
                printf("%d
    ", t[K_th(Root, a)].val);
            }
            else if(opt == 5)
            {
                Split2(Root, a - 1, x, y);
                printf("%d
    ", t[K_th(x, t[x].siz)].val);
                Root = Merge(x, y);
            }
            else
            {
                Split2(Root, a, x, y);
                printf("%d
    ", t[K_th(y, 1)].val);
                Root = Merge(x, y);
            }
        }
        return 0;
    }
    zZhBr
  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/BriMon/p/8975152.html
Copyright © 2011-2022 走看看