zoukankan      html  css  js  c++  java
  • [模板] 替罪羊树

    //Stay foolish,stay hungry,stay young,stay simple
    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cctype> 
    
    int rd() {
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c)) {
            ret=ret*10+c-'0';
            c=getchar();
        }
        return ret*f;
    }
    
    const int MAXN=200000;
    const double alpha = 0.75;
    struct Node{
        int l,r,val;
        int size,cnt;
        bool exist;
    }node[MAXN];
    int cur[MAXN];
    int mem[MAXN];
    int root,pos,pool,cnt,to_rebuild;
    
    bool isbad(int now){
        if((double)node[now].cnt*alpha<=(double)std::max(node[node[now].l].cnt,node[node[now].r].cnt))return true;
        return false;
    }
    
    void dfs(int now){
        if(!now) return;
        dfs(node[now].l);
        if(node[now].exist)cur[++pos]=now;
        else mem[++pool]=now;
        dfs(node[now].r);
    }
    
    void build(int L,int R,int &now){
        int mid=(L+R)>>1;
        now=cur[mid];
        if(L==R){
            node[now].l=node[now].r=0;
            node[now].size=node[now].cnt=1;
            return;
        }
        if(L<R)build(L,mid-1,node[now].l);
        else node[now].l=0;
        build(mid+1,R,node[now].r);
        node[now].size=node[node[now].l].size+node[node[now].r].cnt+1;
        node[now].cnt=node[node[now].l].cnt+node[node[now].r].cnt+1;
    }
    
    void rebuild(int &now){
        pos=0;
        dfs(now);
        if(pos)build(1,pos,now);
        else now=0;
    }
    
    int rank(int tar){
        int now=root,ans=1;
        while(now){
            if(node[now].val>=tar)now=node[now].l;
            else{
                ans+=node[node[now].l].cnt+node[now].exist;
                now=node[now].r;
            }
        }
        return ans;
    }
    
    void inst(int &now,int val){
        if(!now){
            now=mem[pool--];
            node[now].val=val;
            node[now].cnt=node[now].size=1;
            node[now].exist=true;
            node[now].l=node[now].r=0;
            return;
        }
        node[now].size++;node[now].cnt++;
        if(node[now].val>=val) inst(node[now].l,val);
        else inst(node[now].r,val);
        if(!isbad(now)){
            if(to_rebuild){
                if(node[now].l==to_rebuild)rebuild(node[now].l);
                else rebuild(node[now].r);
                to_rebuild=0;
            }
        }else to_rebuild=now;
    }
    
    void del_pos(int &now,int tar){
        if(node[now].exist&&node[node[now].l].cnt+1==tar){
            node[now].exist = false;
            node[now].cnt--;
            return;
        }
        node[now].cnt--;
        if(node[node[now].l].cnt+node[now].exist>=tar) del_pos(node[now].l,tar);
        else del_pos(node[now].r,tar-node[node[now].l].cnt-node[now].exist);
    }
    
    void del_val(int tar){
        del_pos(root,rank(tar));
        if((double)node[root].size*alpha>node[root].cnt) rebuild(root);
    }
    
    int kth(int tar){
        int now=root;
        while(now){
            if(node[now].exist&&node[node[now].l].cnt+1==tar) return node[now].val;
            else if(node[node[now].l].cnt>=tar) now=node[now].l;
            else{
                tar-=node[node[now].l].cnt+node[now].exist;//
                now=node[now].r;
            }
        }
        return 0;
    }
    
    int main() {
        int num,a,b;
        root=0;
        for(int i=MAXN; i>=1; --i)mem[++pool]=i; //初始化内存池
        num=rd();
        while(num--) {
            a=rd();
            b=rd();
            switch(a) {
                case 1: {
                    inst(root,b);
                    break;
                }
                case 2: {
                    del_val(b);
                    break;
                }
                case 3: {
                    printf("%d
    ",rank(b));
                    break;
                }
                case 4: {
                    printf("%d
    ",kth(b));
                    break;
                }
                case 5: {
                    printf("%d
    ",kth(rank(b)-1));
                    break;
                }
                case 6: {
                    printf("%d
    ",kth(rank(b+1)));
                    break;
                }
            }
        }
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247422.html

  • 相关阅读:
    RHCE考试要求
    c语言:md5函数
    c语言:计算输入字符个数
    IP数据报之Internet Header Length
    常用的tar和rpm命令参数
    Oracle数据库实例的创建、删除、修改【转载】
    Internal类或Internal成员讲解
    序列化与反序列化 BinaryFormatter.Serialize 方法 (Stream, Object)
    oracle网络配置listener.ora、sqlnet.ora、tnsnames.ora
    Oracle启动模式及其常见问题探讨
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247422.html
Copyright © 2011-2022 走看看