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

    存个板子

    // Cease to struggle and you cease to live
    // a.cpp
    // Created by hjj on 2019_07_17 16:24
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXM = 100005 * 15;
    struct BST{
        int val[MAXM], ext[MAXM], fa[MAXM];
        int sz[MAXM], tsz[MAXM];
        int son[MAXM][2];
        
        int root;
        double alp;
        int stn, st[MAXM];
        
        BST(){
            stn = MAXM - 1; 
            for(int i = 0; i < MAXM; i++) 
                st[i] = i;
            root = 0;
            alp = 0.7;
        }
        int newnode(int x) {
            int v = st[--stn];
            val[v] = x; ext[v] = 1;fa[v] = 0;
            sz[v] = tsz[v] = 0;
            son[v][0] = son[v][1] = 0;
            return v;
        }
        void push_up(int x) {
            sz[x] = ext[x];tsz[x] = 1;
            if(son[x][0]) {
                sz[x] += sz[son[x][0]];
                tsz[x] += tsz[son[x][0]];
            }
            if(son[x][1]) {
                sz[x] += sz[son[x][1]];
                tsz[x] += tsz[son[x][1]];
            }
        
        }
    
        bool isBad(int v) {
            return (double(tsz[ son[v][0] ]) > double(tsz[v]) * alp) || 
                (double(tsz[ son[v][1] ]) > double(tsz[v]) * alp) ||
                (sz[v] * 2 < tsz[v]);
        }
        vector<int> vec;
        void rebuild_dfs(int v) {
            if(son[v][0]) rebuild_dfs(son[v][0]);
            if(ext[v])vec.push_back(v);else st[stn++] = v;
            if(son[v][1]) rebuild_dfs(son[v][1]);
        }
        int rebuild_build(int l, int r) {
            int mid = (l + r) >> 1, v = vec[mid];
            son[v][0] = (l <= mid-1) ? rebuild_build(l, mid - 1) : 0;
            if(son[v][0]) fa[son[v][0]] = v;
            son[v][1] = (mid+1 <= r) ? rebuild_build(mid + 1, r) : 0;
            if(son[v][1]) fa[son[v][1]] = v;
            push_up(v);
            return v;
        }
        void rebuild(int v) {
            if(isBad(v)){
                vec.clear();
                int tfa = fa[v], lr = son[tfa][1] == v;
                rebuild_dfs(v);
                int u = 0;
                if(vec.size()) u = rebuild_build(0, vec.size() - 1);
                if(tfa == 0) fa[u] = 0, root = u; 
                else{
                    son[tfa][lr] = u;
                    if(u)fa[u] = tfa;
                }
            }
        }
        void ins(int x) {
            int p = root, q = root;
            for(;p && val[p] != x; q = p, p = son[p][ val[p] < x]) ;
            if(!q) {
                p = root = newnode(x);
            }else if(p) {
                ext[p]++;
            }else{
                fa[p = son[q][val[q] < x] = newnode(x) ] = q;
            }
            int fg = 0;
            for(;p;p = fa[p]) {
                push_up(p);
                if(isBad(p)) fg = p;
            }    
            if(fg) rebuild(fg);
        }
        void del(int x) {
            int p = root;
            for(;p && val[p] != x; p = son[p][ val[p] < x]);
            if(p && ext[p]){
                --ext[p];
                int fg = 0;
                for(;p; p = fa[p]) {
                    push_up(p);
                    if(isBad(p)) fg = p;
                }
                if(fg) rebuild(fg);
            }
        }
        int get_rank(int x) {
            int ret = 0;
            for(int p = root;p;) {
                if(val[p] < x) {
                    ret += sz[son[p][0]] + ext[p];
                    p = son[p][1];
                }else p = son[p][0];
            }
            return ret + 1;
        }
        int get_Kth(int p, int k) {
            if(sz[son[p][0]] >= k) return get_Kth(son[p][0] ,k);
            k -= sz[son[p][0]];
            if(ext[p] >= k) return val[p];
            k -= ext[p];
            return get_Kth(son[p][1], k);
        }
        int pre(int x) {
            int id = get_rank(x);
            return get_Kth(root, id - 1);
        }
        int nxt(int x) {
            int id = get_rank(x + 1);
            return get_Kth(root ,id);
        }
    }T;
    
    int main() {
        //ios::sync_with_stdio(0); cin.tie(0); cout.precision(6); cout << fixed;
        int n; scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            int op, x;
            scanf("%d %d", &op, &x);
            int ans;
            switch(op) {
            case 1 : T.ins(x);break;
            case 2 : T.del(x);break;
            case 3 : 
                ans = T.get_rank(x);
                printf("%d
    ", ans);
                break;
            case 4 : 
                ans = T.get_Kth(T.root, x);
                printf("%d
    ", ans);
                break;
            case 5:
                ans = T.pre(x);
                printf("%d
    ", ans);
                break;
            case 6:
                ans = T.nxt(x);
                printf("%d
    ", ans);
                break;
            }
        }
        return 0;
    }
  • 相关阅读:
    SQL数据去重复 Distinct 和 row_number() over()
    Excel闪退问题解决
    SQL Server 修改服务器登录名称以及密码
    从底层角度看ASP.NET-A low-level Look at the ASP.NET Architecture
    MD5加密
    MD5实例化异常 未能执行FIPS验证加密算法
    JDBC(上)
    自学MySQL第二天
    自学MySQL第一天
    自学JavaWeb第五天jQuery进阶
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/11204002.html
Copyright © 2011-2022 走看看