• treap(bzoj 3224普通平衡树)


    就是贴个版,:-(,心累。

    以下是旋转的:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    const int N = 100000 + 11;
    using namespace std;
    struct treap
    {
        int l,r,key,size,rd,cnt;
        void news(int k)
        {
            size = cnt = 1;key = k; rd = rand();
        }
    }tree[N];
    int n,sum,root,ans;
    void updata(int k)
    {
        tree[k].size = tree[k].cnt + tree[tree[k].l].size + tree[tree[k].r].size;
    }
    void rturn(int &k)
    {
        int t = tree[k].l; tree[k].l = tree[t].r; tree[t].r = k;
        tree[t].size = tree[k].size; updata(k); k = t;
    }
    void lturn(int &k)
    {
        int t = tree[k].r; tree[k].r = tree[t].l; tree[t].l = k;
        tree[t].size = tree[k].size; updata(k); k = t;
    }
    
    void insert(int &k,int x)
    {
        if(k == 0){tree[++sum].news(x);k = sum; return;}
        ++tree[k].size;
        if(tree[k].key == x) ++tree[k].cnt;
        else if(x > tree[k].key)
        {
            insert(tree[k].r,x);
            if(tree[tree[k].r].rd < tree[k].rd)lturn(k);
        }
        else
        {
            insert(tree[k].l,x);
            if(tree[tree[k].l].rd < tree[k].rd) rturn(k);
        }
    }
    
    void del(int &k,int x)
    {
        if(k == 0) return;
        if(tree[k].key == x)
        {
            if(tree[k].cnt > 1) {--tree[k].cnt,--tree[k].size; return;}
            if(tree[k].l * tree[k].r == 0) k = tree[k].l + tree[k].r;
            else if(tree[tree[k].l].rd <  tree[tree[k].r].rd)
                rturn(k), del(k,x);
            else lturn(k), del(k,x);
        }
        else if(x > tree[k].key)
            --tree[k].size, del(tree[k].r,x);
        else --tree[k].size, del(tree[k].l,x);
    
    }
    
    
    int query_rank(int k,int x)
    {
        if(k == 0) return 0;
        if(tree[k].key == x) return tree[tree[k].l].size + 1;
        else if(x > tree[k].key)
            return tree[tree[k].l].size + tree[k].cnt + query_rank(tree[k].r,x);
        else return query_rank(tree[k].l,x);
    }
    
    int query_num(int k,int x)
    {
        if(k == 0)return 0;
        if(x <= tree[tree[k].l].size) return query_num(tree[k].l,x);
        else if(x > tree[tree[k].l].size + tree[k].cnt) return query_num(tree[k].r,x-tree[tree[k].l].size - tree[k].cnt);
        else return tree[k].key;
    }
    
    void query_pro(int k,int x)
    {
        if(k == 0)return;
        if(tree[k].key < x)
            ans = k,query_pro(tree[k].r,x);
        else query_pro(tree[k].l,x);
    }
    
    void query_nxt(int k,int x)
    {
        if(k == 0)return;
        if(tree[k].key > x)
            ans = k,query_nxt(tree[k].l,x);
        else query_nxt(tree[k].r,x);
    }
    
    int main()
    {
        scanf("%d",&n);
        int op,x;
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d%d",&op,&x);
            switch(op)
            {
                case 1: insert(root,x); break;
                case 2: del(root,x); break;
                case 3: printf("%d
    ",query_rank(root,x)); break;
                case 4: printf("%d
    ",query_num(root,x)); break;
                case 5: ans = 0; query_pro(root,x); printf("%d
    ",tree[ans].key); break;
                case 6: ans = 0; query_nxt(root,x); printf("%d
    ",tree[ans].key); break;
            }
        }
        return 0;
    }

    以下是不用旋转的:

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define mp make_pair
    using namespace std;
    const int N = 100000 + 11,inf = 1 << 30;
    typedef pair <int,int> pir;
    int n,ans,size,root;
    struct Treap
    {
        int l,r,key,rnt,size;
        void news(int k)
        {
            size = 1,key = k,rnt = rand();
        }
    }tree[N];
    
    void updata(int x)
    {
        tree[x].size = tree[tree[x].l].size + tree[tree[x].r].size + 1;
    }
    
    pir split(int a,int n)
    {
        if(n == 0) return mp(0,a);
        int l = tree[a].l, r = tree[a].r;
        if(n == tree[l].size){tree[a].l = 0,updata(a); return mp(l,a);}
        if(n == tree[l].size + 1){tree[a].r = 0,updata(a); return mp(a,r);}
        if(n < tree[l].size)
        {
            pir tmp = split(l,n);
            tree[a].l = tmp.second,updata(a); return mp(tmp.first,a);
        }
        pir tmp = split(r,n - tree[l].size - 1);
        tree[a].r = tmp.first,updata(a); return mp(a,tmp.second);
    }
    
    int merge(int a,int b)
    {
        if(a == 0 || b == 0) return a + b;
        if(tree[a].rnt < tree[b].rnt) {tree[a].r = merge(tree[a].r,b),updata(a); return a; }
        else {tree[b].l = merge(a,tree[b].l),updata(b); return b;}
    }
    
    int query_rank(int k,int x)
    {
        int ret = 0, tmp = inf;
        while(k)
        {
            if(x == tree[k].key) tmp = min(tmp,ret + tree[tree[k].l].size + 1);
            //    cout<<tree[k].key<<" "<<tree[tree[k].l].size<<" "<<x<<endl;
            if(x > tree[k].key) ret += tree[tree[k].l].size + 1,k = tree[k].r;
            else k = tree[k].l;
        }
        return tmp == inf?ret:tmp;
    }
    
    void insert(int x)
    {
        int k = query_rank(root,x);
        pir tmp = split(root,k);
        tree[++size].news(x);
        root = merge(tmp.first,size);
        root = merge(root,tmp.second);
    }
    
    
    void del(int x)
    {
        int k = query_rank(root,x);
        pir t1 = split(root,k);
        pir t2 = split(t1.first,k-1);
    //    cout<<t2.first<<" "<<t2.second<<endl;
        root = merge(t2.first,t1.second);
    }
    
    int query_num(int k,int x)
    {
        if(k == 0)return 0;
        if(x <= tree[tree[k].l].size) return query_num(tree[k].l,x);
        else if(x == tree[tree[k].l].size + 1) return tree[k].key;
        return query_num(tree[k].r,x - tree[tree[k].l].size - 1);
    }
    
    
    void query_pro(int k,int x)
    {
        if(k == 0)return;
        if(tree[k].key < x)
            ans = k,query_pro(tree[k].r,x);
        else query_pro(tree[k].l,x);
    }
    
    void query_nxt(int k,int x)
    {
        if(k == 0)return;
        if(tree[k].key > x)
        {
            ans = k, query_nxt(tree[k].l,x);
        }
        else query_nxt(tree[k].r,x);
    }
    
    int main()
    {
        freopen("treap.in","r",stdin);
        scanf("%d",&n);
        int op,x;
        while(n--)
        {
            scanf("%d%d",&op,&x);
            switch(op)
            {
                case 1: insert(x); break;
                case 2: del(x); break;
                case 3: printf("%d
    ",query_rank(root,x)); break;
                case 4: printf("%d
    ",query_num(root,x)); break;
                case 5: ans = 0; query_pro(root,x); printf("%d
    ",tree[ans].key); break;
                case 6: ans = 0; query_nxt(root,x); printf("%d
    ",tree[ans].key); break;
            }
        }
        return 0;
    }

    (还是觉得splay写得好玩)

  • 相关阅读:
    linq获取最大ID值
    asp:MultiView选项卡控件,可以用来选择性的显示需要的部门
    TFS修改工作区映射区
    怎么解决javascript小数相减会出现一长串的小数位数?
    (转)向页面动态载入用户控件和自定义控件的方法(谨记)
    (转)工作经验到底是个什么东东?工作经验从哪里来?
    hdu 5441 travel 离线+带权并查集
    hdu 5438 Ponds dfs
    hdu 5437 Alisha’s Party 模拟 优先队列
    CF 500 B. New Year Permutation 并查集
  • 原文地址:https://www.cnblogs.com/Ateisti/p/6416235.html
Copyright © 2020-2023  润新知