zoukankan      html  css  js  c++  java
  • 替罪羊树板子

    #include <cstdio>
    #define ls ch[now][0]
    #define rs ch[now][1]
    const int N=1e5+10;
    double alpha=0.7;
    int valit[N],siz[N],exist[N],ch[N][2],dat[N],tot,q[N<<2],l=1,r=0,s[N],cnt,root;
    #define bad (siz[now]*alpha<(double)(siz[ls])||siz[now]*alpha<(double)(siz[rs]))
    #define updata siz[now]=siz[ls]+siz[rs]+1,valit[now]=valit[ls]+valit[rs]+exist[now]
    int New(){return l<=r?q[l++]:++tot;}
    void del(int now){q[++r]=now;}
    void dfs(int now)
    {
        if(!now) return;
        dfs(ls);
        if(exist[now])s[++cnt]=dat[now];
        del(now);
        dfs(rs);
    }
    void build(int &now,int l,int r)
    {
        if(l>r){now=0;return;}
        now=New();
        int mid=l+r>>1;
        dat[now]=s[mid];
        exist[now]=1;
        build(ls,l,mid-1),build(rs,mid+1,r);
        updata;
    }
    void rebuild(int &now)
    {
        cnt=0;dfs(now);
        build(now,1,cnt);
    }
    void Insert(int &now,int k)
    {
        if(!now)
        {
            now=New();
            exist[now]=valit[now]=siz[now]=1;
            dat[now]=k;ls=rs=0;
            return;
        }
        ++siz[now],++valit[now];
        if(dat[now]>=k) Insert(ls,k);
        else Insert(rs,k);
        if(bad) rebuild(now);
    }
    int kth(int now,int k)
    {
        if(!now) return 1;
        if(dat[now]>=k) return kth(ls,k);
        else return kth(rs,k)+valit[ls]+exist[now];
    }
    void extrack(int now,int k)
    {
        --valit[now];
        if(k<=valit[ls]) extrack(ls,k);
        else if(k>valit[ls]+exist[now]) extrack(rs,k-valit[ls]-exist[now]);
        else --exist[now];
    }
    int fkth(int now,int k)
    {
        if(k<=valit[ls]) return fkth(ls,k);
        else if(k>valit[ls]+exist[now]) return fkth(rs,k-valit[ls]-exist[now]);
        else return dat[now];
    }
    int main()
    {
        int n;scanf("%d",&n);
        for(int opt,x,i=1;i<=n;i++)
        {
            scanf("%d%d",&opt,&x);
            if(opt==1) Insert(root,x);
            else if(opt==2) extrack(root,kth(root,x));
            else if(opt==3) printf("%d
    ",kth(root,x));
            else if(opt==4) printf("%d
    ",fkth(root,x));
            else if(opt==5) printf("%d
    ",fkth(root,kth(root,x)-1));
            else printf("%d
    ",fkth(root,kth(root,x+1)));
        }
        return 0;
    }
    

    码量和FHQ差不过,但目前感觉FHQ好写一点。

    复杂度保证有一点是懒惰删除,可以根据朝鲜树感性理解。

  • 相关阅读:
    文件I/O(二)
    linux学习之文件I/O篇(一)
    静态库和共享库
    vim-ide
    CentOS6 vsftpd 安装及优化方法
    Redmine2.5+CentOS6+Apache2
    分享一个TP5实现Create()方法的心得
    Windows证书的生成导出以及使用证书验证文件是否被修改
    如何设置程序UAC控制
    关于C#的可变长参数
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9859973.html
Copyright © 2011-2022 走看看