其他分享
首页 > 其他分享> > 【模板】替罪羊树

【模板】替罪羊树

作者:互联网

同【普通平衡树】

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const double alpha=0.7;

struct node{
    #define ls(x) t[x].lc
    #define rs(x) t[x].rc
    int lc,rc,val,size,sum,cnt;
}t[maxn];
int tot,root;
inline int newnode(int val){
    ++tot,t[tot].val=val,t[tot].cnt=t[tot].sum=t[tot].size=1;
    return tot;
}
inline bool isbad(int x){
    return (double)max(t[ls(x)].sum,t[rs(x)].sum)>t[x].sum*alpha;
}
inline void pushup(int x){
    t[x].size=t[ls(x)].size+t[rs(x)].size+t[x].cnt;
    t[x].sum=t[ls(x)].sum+t[rs(x)].sum+t[x].cnt;
}
inline void dfs(int x,vector<int> &v){
    if(ls(x))dfs(ls(x),v);
    if(t[x].cnt)v.push_back(x);
    if(rs(x))dfs(rs(x),v);
}
inline int build(int l,int r,vector<int> &v){
    if(l>r)return 0;
    int mid=l+r>>1;
    int x=v[mid];
    ls(x)=build(l,mid-1,v),rs(x)=build(mid+1,r,v);
    pushup(x);
    return x;
}
inline void rebuild(int &x){
    vector<int> v;
    dfs(x,v);
    x=build(0,v.size()-1,v);
}
void insert(int &x,int val){
    if(!x)x=newnode(val);
    else if(val==t[x].val)++t[x].cnt;
    else if(val<t[x].val)insert(ls(x),val);
    else insert(rs(x),val);
    pushup(x);
    if(isbad(x))rebuild(x);
}
void remove(int &x,int val){
    if(!x)return;
    else if(t[x].val==val)--t[x].cnt;
    else if(val<t[x].val)remove(ls(x),val);
    else remove(rs(x),val);
    pushup(x);
    if(isbad(x))rebuild(x);
}
int kth(int x,int k){//cmp with size -> we can ignore the remove tag
    if(k<=t[ls(x)].size)return kth(ls(x),k);
    else if(k>t[ls(x)].size+t[x].cnt)return kth(rs(x),k-t[ls(x)].size-t[x].cnt);
    else return t[x].val;
}
int getrank(int x,int val){//cmp with size -> we can ignore the remove tag
    if(val==t[x].val)return t[ls(x)].size+1;
    else if(val<t[x].val)return getrank(ls(x),val);
    else return getrank(rs(x),val)+t[ls(x)].size+t[x].cnt;
}
int upper(int x,int val){
    if(!x)return 1;
    else if(t[x].cnt&&val==t[x].val)return t[x].cnt+t[ls(x)].size+1;
    else if(val<t[x].val)return upper(ls(x),val);
    else return t[x].cnt+t[ls(x)].size+upper(rs(x),val);
}
int lower(int x,int val){
    if(!x)return 0;
    else if(t[x].cnt&&val==t[x].val)return t[ls(x)].size;
    else if(val<t[x].val)return lower(ls(x),val);
    else return t[x].cnt+t[ls(x)].size+lower(rs(x),val);
}

int main(){
    int n;scanf("%d",&n);
    while(n--){
        int opt,val;scanf("%d%d",&opt,&val);
        if(opt==1)insert(root,val);
        else if(opt==2)remove(root,val);
        else if(opt==3)printf("%d\n",getrank(root,val));
        else if(opt==4)printf("%d\n",kth(root,val));
        else if(opt==5)printf("%d\n",kth(root,lower(root,val)));
        else if(opt==6)printf("%d\n",kth(root,upper(root,val)));
    }
    return 0;
}

标签:cnt,val,rs,int,替罪羊,ls,模板,size
来源: https://www.cnblogs.com/wzj-xhjbk/p/10387748.html