• 【封装】替罪羊树


    struct ScopeGoat_Tree{ 
        #define ls p[x].son[0]
        #define rs p[x].son[1]
        #define N 100005
        const double alpha = 0.75;
    
        int rt, tot, cnt;
        int cur[N], res[N];
    
        struct Node{
            int val, siz, real;
            int son[2];
            bool exist;
        }p[N];
    
        void init(){
            for(int i = N - 1; i; --i)  res[++tot] = i;
        }
    
        void ins(int &x, int val){
            if(!x){
                x = res[tot--];
                p[x].val = val, p[x].exist = 1;
                p[x].real = p[x].siz = 1;
                ls = rs = 0;
                return ;
            }
            ++p[x].siz,  ++p[x].real;
            if(val <= p[x].val)  ins(ls, val);
            else    ins(rs, val);
        }
    
        inline bool balance(int x){
            return p[x].real * alpha > 1.0 * max(p[ls].real, p[rs].real);
        }
    
        inline void pushup(int x){
            p[x].siz = p[ls].siz + p[rs].siz + 1;
            p[x].real = p[ls].real + p[rs].real + 1;
        }
    
        void traversal(int x){
            if(!x)  return ;
            traversal(ls);
            if(p[x].exist)  cur[++cnt] = x;
            else    res[++tot] = x;
            traversal(rs);
        }
    
        void setup(int l, int r, int &x){
            int mid = ((l + r) >> 1);
            x = cur[mid];
            if(l == r){
                p[x].son[0] = p[x].son[1] = 0;
                p[x].siz = p[x].real = 1;
            }
            if(l < mid)  setup(l, mid - 1, ls);
            else    p[x].son[0] = 0;
            if(r > mid)  setup(mid + 1, r, rs);
            else    p[x].son[1] = 0;
            pushup(x);
        }
    
        void rebuild(int &x){
            cnt = 0;
            traversal(x);
            if(cnt)  setup(1, cnt, x);
            else    x = 0;
        }
    
        void check(int x, int val){
            int s = (val <= p[x].val ? 0 : 1);
            while(p[x].son[s]){
                if(!balance(p[x].son[s])){
                    rebuild(p[x].son[s]);
                    return ;
                }
                x = p[x].son[s],  s = (val <= p[x].val ? 0 : 1);
            }
        }
    
        int get_rank(int val){
            int x = rt, rk = 1;
            while(x){
                if(p[x].val >= val)  x = ls;
                else    rk += p[ls].real + p[x].exist,  x = rs;
            }
            return rk;
        }
    
        int get_val(int rk){
            int x = rt;
            while(x){
                if(p[x].exist && p[ls].real + 1 == rk)  return p[x].val;
                else if(p[ls].real >= rk)  x = ls;
                else    rk -= p[x].exist + p[ls].real,  x = rs;
            }
        }
    
        void del_rank(int &x, int rk){
            if(p[x].exist && !((p[ls].real + 1) ^ rk)){
                p[x].exist = 0,  --p[x].real;
                return ;
            }
            --p[x].real;
            if(p[ls].real + p[x].exist >= rk)   del_rank(ls, rk);
            else  del_rank(rs, rk - p[x].exist - p[ls].real);
        }
    
        void del_val(int val){
            del_rank(rt, get_rank(val));
            if(alpha * p[rt].siz > 1.0 * p[rt].real)    rebuild(rt);
        }
    }Tree;
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    OpenGL入门1.3:着色器 GLSL
    OpenGL入门1.2:渲染管线简介,画三角形
    C++回调,函数指针
    JavaScript 比较和逻辑运算符
    JS 运算符
    JS 函数
    JS 对象
    JS 数据类型
    JS 变量
    JS 注释
  • 原文地址:https://www.cnblogs.com/214txdy/p/14023956.html
Copyright © 2020-2023  润新知