• 平衡树-Splay


    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define inf (int)(1e9+1000)
    #define maxn (int)(1e5+1000)
    using namespace std;
    int fa[maxn],size[maxn],cnt[maxn],son[maxn][2],val[maxn];
    int n,root,beh,fro,idx;
    void maintain(int x){
        size[x]=cnt[x];
        if(son[x][0])size[x]+=size[son[x][0]];
        if(son[x][1])size[x]+=size[son[x][1]];
        return;
    }
    void clear(int x){
        int y=fa[x];fa[x]=0;
        if(!x)return;//test
        if(son[y][0]==x)son[y][0]=0;
        else son[y][1]=0;
        return;
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],o=(son[y][1]==x);
    
        son[y][o]=son[x][o^1];
        fa[son[x][o^1]]=y;
    
        son[x][o^1]=y;
        fa[y]=x;
    
        son[z][son[z][1]==y]=x;
        fa[x]=z;
    
        maintain(y);
        maintain(x);
    }
    void splay(int x){
        for(int y;(y=fa[x]);rotate(x)){
            if(!fa[y])continue;
            rotate(((son[fa[y]][0]==y)==(son[fa[x]][0]==x))?y:x);
        }
        root=x;
    }
    void insert(int x,int a){
        int y=0;
        while(x&&val[x]!=a){
            y=x;
            x=son[x][a>val[x]];
        }
        if(x){
            size[x]++;cnt[x]++;
        }
        else{
            x=++idx;
            cnt[x]=1;
            fa[x]=y;
            son[y][a>val[y]]=x;
            size[x]=1;
            val[x]=a;
        }
        splay(x);
    }
    void del(int x){
        splay(x);
        if(cnt[x]>1){cnt[x]--;maintain(x);splay(x);return;}
        root=son[x][1];int move=son[x][0];
        clear(son[x][0]);clear(son[x][1]);
        int y=0,now=root;
        while(now){
            y=now;size[y]+=size[move];
            now=son[now][0];
        }
        fa[move]=y;son[y][0]=move;
        splay(move);
        return;
    }
    void pre(int x,int a){
        if(!x)return;
        while(x){
            if(val[x]<a){
                fro=x;
                x=son[x][1];
            }else{
                x=son[x][0];
            }
        }
        return;
    }
    void suc(int x,int a){
        if(!x)return;
        while(x){
            if(val[x]>a){
                beh=x;
                x=son[x][0];
            }
            else{
                x=son[x][1];
            }
        }
        return;
    }
    int kth(int x,int a){
        while(1){
            if(a<=size[son[x][0]]){//test
                x=son[x][0];
            }
            else{
                a-=size[son[x][0]]+cnt[x];
                if(a<=0)return x;
                x=son[x][1];
            }
        }
        return 0;
    }
    int rk(int x,int a){
        int rank=0;
        while(1){
            if(a<val[x]){
                x=son[x][0];
            }
            else{
                rank+=size[son[x][0]];
                if(a==val[x]){
                    splay(x);
                    return rank+1;
                }
                rank+=cnt[x];
                x=son[x][1];
            }
        }
        return rank;
    }
    int get(int a){
        int x=root;
        while(1){
            if(val[x]==a)return x;
            x=son[x][a>val[x]];
        }
        return 0;
    }
    int main(){
        scanf("%d",&n);
        insert(root,inf);insert(root,-inf);
        for(int i=1;i<=n;i++){
            int opt,x;scanf("%d%d",&opt,&x);
            if(opt==1)insert(root,x);
            else if(opt==2)del(get(x));
            else if(opt==3)printf("%d
    ",rk(root,x)-1);
            else if(opt==4)printf("%d
    ",val[kth(root,x+1)]);
            else if(opt==5){pre(root,x);printf("%d
    ",val[fro]);}
            else if(opt==6){suc(root,x);printf("%d
    ",val[beh]);}
        }
    }
    
  • 相关阅读:
    Oracle查询今天的数据(昨天、本周...)
    Windows添加删除 route
    大三寒假学习进度(九)
    大三寒假学习进度(八)
    大三寒假学习进度(七)
    大三寒假学习进度(六)
    大三寒假学习进度(五)
    《软件架构师应该知道的97件事》阅读笔记(一)
    大三寒假学习进度(四)
    大三寒假学习进度(三)
  • 原文地址:https://www.cnblogs.com/GavinZheng/p/10758644.html
Copyright © 2020-2023  润新知