zoukankan      html  css  js  c++  java
  • 【封装】替罪羊树

    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;
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    HDOJ 2095 find your present (2)
    HDOJ 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你
    九度 1337 寻找最长合法括号序列
    九度 1357 疯狂地Jobdu序列
    HDOJ 1280 前m大的数
    九度 1343 城际公路网
    九度 1347 孤岛连通工程
    HDOJ 2151 Worm
    九度 1342 寻找最长合法括号序列II
    九度 1346 会员积分排序
  • 原文地址:https://www.cnblogs.com/214txdy/p/14023956.html
Copyright © 2011-2022 走看看