[bzoj3224]普通平衡树

[bzoj3224]普通平衡树


平衡树板子。因为懒得删点,这里直接num--,然后要注意查询前驱后继的时候不能直接输出只能(我只会)再查一遍Kth

写得丑别打我

  • 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct Splay{
    int ch[2],fa;
    int sum,num,sz;
}t[N];
int null=0,cnt,root;
inline bool son(int x){return t[t[x].fa].ch[1]==x;}
inline bool isroot(int x){return t[t[x].fa].ch[1]!=x&&t[t[x].fa].ch[0]!=x;}
inline int newnode(int _val){
    cnt++;t[cnt].sum=_val,t[cnt].num++,t[cnt].sz=1;
    return cnt;
}
inline void pushup(int x){
    t[x].sz=t[x].num;
    if(t[x].ch[1])t[x].sz+=t[t[x].ch[1]].sz;
    if(t[x].ch[0])t[x].sz+=t[t[x].ch[0]].sz;
}
inline void rotate(int x){
    int f=t[x].fa,gf=t[t[x].fa].fa;
    bool a=son(x),b=son(x)^1;
    if(!isroot(f))t[gf].ch[son(f)]=x;
    t[x].fa=gf;
    t[f].ch[a]=t[x].ch[b];t[t[x].ch[b]].fa=f;
    t[x].ch[b]=f;t[f].fa=x;
    pushup(f);pushup(x);//"pushup
}
inline void splay(int x){
    while(!isroot(x)){
        int f=t[x].fa;
        if(!isroot(f)){
            if(son(f)^son(x))rotate(x);
            else rotate(f);
        }
        rotate(x);
    }
    root=x;
}
inline void ins(int v){
    if(!root){root=newnode(v);return;}
    int nw=root;
    while(true){
        t[nw].sz++;
        if(t[nw].sum>v){
            if(t[nw].ch[0])nw=t[nw].ch[0];
            else {
                t[nw].ch[0]=newnode(v);t[cnt].fa=nw;
                nw=t[nw].ch[0];break;
            }
        }else if(t[nw].sum<v){
            if(t[nw].ch[1])nw=t[nw].ch[1];
            else {
                t[nw].ch[1]=newnode(v);t[cnt].fa=nw;
                nw=t[nw].ch[1];break;
            }
        }else if(t[nw].sum==v){t[nw].num++;break;}
    }
    splay(nw);
}
inline void del(int v){
    int nw=root;
    while(true){
        t[nw].sz--;
        if(t[nw].sum>v) nw=t[nw].ch[0];
        else if(t[nw].sum<v) nw=t[nw].ch[1];
        else if(t[nw].sum==v){t[nw].num--;break;}
    }
    splay(nw);
}
inline int Kth(int rk){
    int nw=root;
    while(true){
        int l=t[t[nw].ch[0]].sz+1;
        int r=l+t[nw].num-1;
        if(rk<=r&&rk>=l)break;
        else if(rk<=l-1) nw=t[nw].ch[0];
        else if(rk>r){
            rk-=r;nw=t[nw].ch[1];
        }
    }
    splay(nw);
    return t[nw].sum;
}
inline int PRE(int v){
    int id=-1,nw=root;
    while(true){
        if(nw==null)break;
        if(t[nw].sum<v){
            id=nw;nw=t[nw].ch[1];
        }
        else nw=t[nw].ch[0];
    }
    splay(id);
    return Kth(t[t[id].ch[0]].sz+t[id].num);
}
inline int AFT(int v){
    int id=-1,nw=root;
    while(true){
        if(nw==null)break;
        if(t[nw].sum>v){
            id=nw;nw=t[nw].ch[0];
        }
        else nw=t[nw].ch[1];
    }
    splay(id);
    return Kth(t[t[id].ch[0]].sz+1);
}

inline int ask(int v){
    int nw=root;
    while(true){
        if(t[nw].sum==v) break;
        else if(t[nw].sum<v) nw=t[nw].ch[1];
        else if(t[nw].sum>v) nw=t[nw].ch[0];
    }
    splay(nw);
    return t[t[nw].ch[0]].sz+1;
}

int T;
int main()
{
    scanf("%d",&T);
    while(T--){
        int opt,x;
        scanf("%d%d",&opt,&x);
        if(opt==1) ins(x);
        else if(opt==2) del(x);
        else if(opt==3) printf("%d\n",ask(x));
        else if(opt==4) printf("%d\n",Kth(x));
        else if(opt==5) printf("%d\n",PRE(x));
        else if(opt==6) printf("%d\n",AFT(x));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_35923186/article/details/83042773