• bzoj3224Treap


    Splay版本的会补。。。

    在学了2个小时Splay之后深感Treap的优越

    特地又花了20分钟打了个Treap

    至于这些平衡树的优缺点 可以用平衡方式来直观的感受到

    现在平衡树们面对着这样的一个问题:“二叉搜索树退化成O(n)”怎么办

    Splay说:下面退不退化我不管 我把要查询的点转到根节点上

    替罪羊树说:我看哪块不平衡了 我就把它拍扁重建弄成平衡的

    SBT说:我旋转强行让深度为logn

    RBT说:我手动给每个点打标签让他们出现各种性质然后旋转

    而Treap说:在座的各位都是辣鸡 普通的二叉查找树对于随机数据不是平衡的吗?我随机给每个点分派一个数据 让整棵树对于这个随机数据平衡

    Splay&替罪羊树&SBT&RBT:Orz

    大概就是这样吧

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int maxn=100010;
    const int inf=1e9;
    const int mod=1000000;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='0')f=-f;ch=getchar();}
        while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}
        return x*f;
    }
    struct Treenode
    {
        int l,r,v,rnd,size,w;
    }; 
    inline int ran()
    {
        static int seed=1364684679;
        seed+=(seed<<2)+1;
        return seed;
    }
    struct Treap
    {
        Treenode tr[maxn];
        int root,Size,ans;
        inline void update(int k){tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w;}
        inline void Leftr(int &k)
        {
            int t=tr[k].r;  
            tr[k].r=tr[t].l;  
            tr[t].l=k;  
            tr[t].size=tr[k].size;  
            update(k);  
            k=t; 
        }
        inline void Rightr(int &k)
        {
            int t=tr[k].l;
            tr[k].l=tr[t].r;
            tr[t].r=k;
            tr[t].size=tr[k].size;
            update(k);
            k=t; 
        }
        inline void insert(int &k,int x)  
        {
            if(k==0)  
            {  
                Size++;  
                k=Size;  
                tr[k].size=tr[k].w=1 ;  
                tr[k].v=x;  
                tr[k].rnd=ran();  
                return;
            }  
            tr[k].size++;  
            if(tr[k].v==x)tr[k].w++;  
            else if(x>tr[k].v)  
            {  
                insert(tr[k].r,x) ;  
                if(tr[tr[k].r].rnd<tr[k].rnd)Leftr(k) ;  
            }
            else   
            {  
                insert(tr[k].l,x) ;  
                if(tr[tr[k].l].rnd<tr[k].rnd)Rightr(k) ;  
            }  
        }
        inline void del(int &k,int x)  
        {  
            if(k==0) return;  
            if(tr[k].v==x)  
            {  
                if(tr[k].w>1) {tr[k].w--,tr[k].size--;return;}  
                if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;  
                else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd){Rightr(k);del(k,x);}
                else{Leftr(k);del(k,x);}  
            }
            else if(x>tr[k].v){tr[k].size--;del(tr[k].r,x);}
            else{tr[k].size--;del(tr[k].l,x);}  
        }  
        inline int query_rank(int k,int x)
        {
            if(k==0) return 0;  
            if(tr[k].v==x) return tr[tr[k].l].size+1 ;  
            else if(x>tr[k].v) return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x) ;  
            else return query_rank(tr[k].l,x) ;
        }
        inline int query_num(int k,int x)  
        {  
            if(k==0) return 0;  
            if(x<=tr[tr[k].l].size)return query_num(tr[k].l ,x) ;  
            else if(x>tr[tr[k].l].size+tr[k].w)return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w);
            else return tr[k].v;  
        }  
        inline void query_pro(int k,int x)  
        {  
            if(k==0)return;  
            if(tr[k].v<x)  
            {  
                ans=k ;  
                query_pro(tr[k].r,x);  
            }
            else query_pro(tr[k].l,x);  
        }  
        inline void query_sub(int k,int x)  
        {  
            if(k==0) return;  
            if(tr[k].v>x)  
            {  
                ans=k;  
                query_sub(tr[k].l,x);  
            }
            else query_sub(tr[k].r,x);  
        }
    }treap;
    
    int main()
    {
        int n;
        scanf("%d",&n);
        int op,x;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&op,&x);
            if(op==1)treap.insert(treap.root,x);
            if(op==2)treap.del(treap.root,x);
            if(op==3)printf("%d
    ",treap.query_rank(treap.root,x));
            if(op==4)printf("%d
    ",treap.query_num(treap.root,x));
            if(op==5){treap.ans=0;treap.query_pro(treap.root,x);printf("%d
    ",treap.tr[treap.ans].v);}
            if(op==6){treap.ans=0;treap.query_sub(treap.root,x);printf("%d
    ",treap.tr[treap.ans].v);}
        }
    }
    View Code
  • 相关阅读:
    2020年12月学习记录
    Data Protection Application Programming Interface滥用攻击
    另类的缓存凭证收集
    js获取地址栏参数,携带参数跳转页面
    用JS获取地址栏参数的方法
    解决vue加载时闪烁
    vue-cli-service build 不同环境配置
    vite创建vue3.x项目报404的解决方案
    后端开发完接口才给出接口文档,合理吗?
    API研发实现规范化管理的价值
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/7781044.html
Copyright © 2020-2023  润新知