替罪羊树

存个板子

// 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\n", ans);
            break;
        case 4 : 
            ans = T.get_Kth(T.root, x);
            printf("%d\n", ans);
            break;
        case 5:
            ans = T.pre(x);
            printf("%d\n", ans);
            break;
        case 6:
            ans = T.nxt(x);
            printf("%d\n", ans);
            break;
        }
    }
    return 0;
}

 

posted @ 2019-07-17 22:05  hjj1871984569  阅读(159)  评论(0编辑  收藏  举报