【封装】替罪羊树

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;
你只有十分努力,才能看上去毫不费力。
原文地址:https://www.cnblogs.com/214txdy/p/14023956.html