ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3369 【模板】普通平衡树 替罪羊树解法

2022-03-20 08:03:09  阅读:155  来源: 互联网

标签:ch cur int siz 替罪羊 P3369 rc 模板 lc


P3369 【模板】普通平衡树

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define lc ch[p][0]
#define rc ch[p][1]
using namespace std;
const int N=100010;
const int inf=0x3f3f3f3f;
const double alpha=0.75;
int n,m;
int rt=1,tot=1;
int loc[N],sum;
int ch[N][2],fa[N];
double siz[N];
int val[N];
inline void pushup(int p){
    siz[p]=siz[lc]+siz[rc]+1;
}
inline bool banlc(int p){
    if(siz[lc]>siz[p]*alpha) return 0;
    if(siz[rc]>siz[p]*alpha) return 0;
    return 1;
}
void build(int &p,int L,int R){
    if(L>R){
        p=0;    
        return;
    }
    int mid=(L+R)>>1;
    p=loc[mid];
    build(lc,L,mid-1);
    build(rc,mid+1,R);
    if(lc) fa[lc]=p;
    if(rc) fa[rc]=p;
    pushup(p);
}
void DFS(int p){
    if(!p) return;
    if(lc) DFS(lc);
    loc[++sum]=p;
    if(rc) DFS(rc);
}
void rebuild(int p){
    sum=0;
    DFS(p);
    int f0=fa[p];
    bool b=(ch[f0][0]!=p);
    int cur;
    build(cur,1,sum);
    fa[cur]=f0;
    ch[f0][b]=cur;
    if(p==rt) rt=cur;
}
void ins(int v){
    int p=rt,cur=++tot;
    siz[cur]=1;
    val[cur]=v;
    bool b;
    while(1){
        siz[p]++;
        b=(v>=val[p]);
        if(ch[p][b]) p=ch[p][b];
        else{
            ch[p][b]=cur;
            fa[cur]=p;
            break;
        }
    }
    int pos=0;
    for(int i=cur;i;i=fa[i]){
        if(!banlc(i)) pos=i;
    }
    if(pos) rebuild(pos);
}
inline int getpos(int p,int v){
    while(1){
        if(val[p]==v) return p;
        if(v>val[p]) p=rc;
        else p=lc;
    }
}
inline void del(int v){
    int p=getpos(rt,v);
    if(lc&&rc){
        int cur=lc;
        while(ch[cur][1]) cur=ch[cur][1];
        val[p]=val[cur];
        p=cur; 
    }
    int son=lc?lc:rc;
    int f0=fa[p];
    bool b=ch[f0][0]!=p;
    ch[f0][b]=son;
    fa[son]=f0;
    for(int i=fa[p];i;i=fa[i]) siz[i]--;
    if(p==rt) rt=son;
}
inline int getrank(int p,int v){
    int ret=0;
    while(p){
        if(v>val[p]) ret+=siz[lc]+1,p=rc;
        else p=lc;
    }
    return ret;
}
inline int kth(int p,int k){
    while(1){
        if(k<=siz[lc]) p=lc;
        else if(k==siz[lc]+1) return p;
        else k-=siz[lc],k--,p=rc;
    }
}
inline int getpre(int p,int v){
    int ret=-inf;
    while(p){
        if(v>val[p]) ret=max(ret,val[p]),p=rc;
        else p=lc;
    }
    return ret;
}
inline int getsuc(int p,int v){
    int ret=inf;
    while(p){
        if(v<val[p]) ret=min(ret,val[p]),p=lc;
        else p=rc;
    }
    return ret;
}
int main(){
    scanf("%d",&n);
    siz[rt]=1;
    val[rt]=-inf;
    int op,x;
    while(n--){
        scanf("%d%d",&op,&x);
        if(op==1) ins(x);
        if(op==2) del(x);
        if(op==3) printf("%d\n",getrank(rt,x));
        if(op==4) printf("%d\n",val[kth(rt,x+1)]);
        if(op==5) printf("%d\n",getpre(rt,x));
        if(op==6) printf("%d\n",getsuc(rt,x));
    }
    return 0;
}

  

标签:ch,cur,int,siz,替罪羊,P3369,rc,模板,lc
来源: https://www.cnblogs.com/smghj/p/16028906.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有