• BZOJ3224: Tyvj 1728 普通平衡树


    题解:权值平衡树  按题意模拟即可

    #include <bits/stdc++.h>
    #define rt ch[ch[root][1]][0]
    const int MAXN=1e5+10;
    const int inf=1e9+10;
    using namespace std;
    int ch[MAXN][2],root,pre[MAXN],size[MAXN],key[MAXN],cnt,maxn[MAXN];
    void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;maxn[x]=max(max(maxn[ch[x][0]],maxn[ch[x][1]]),key[x]);}
    void Treavel(int x)
    {
        if(x)
        {
        //	cout<<x<<endl;
            Treavel(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d
    ",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug(int rp)
    {
        printf("root:%d
    ",rp);
        Treavel(rp);
    }
    void newnode(int &x,int fa,int vul){
        x=++cnt;ch[x][0]=ch[x][1]=0;pre[x]=fa;size[x]=1;maxn[x]=key[x]=vul;
    }
    void rotate(int x,int kind){
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
        if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);
    }
    void splay(int x,int goal){
        while(pre[x]!=goal){
            if(pre[pre[x]]==goal) rotate(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x];int kind=ch[pre[y]][0]==y;
                if(ch[y][kind]==x) rotate(x,!kind),rotate(x,kind);
                else rotate(y,kind),rotate(x,kind);
             }
        }
        if(goal==0) root=x;
        up(x);
    }
    int minn;
    int find1(int x,int vul){
        //if(!x) return ;
        if(key[x]==vul){
            if(maxn[ch[x][0]]==vul) return find1(ch[x][0],vul);
            else return x;
        }
        else if(key[x]<vul)  return find1(ch[x][1],vul);
        else  return find1(ch[x][0],vul);
    }
    int find2(int x,int siz){
        if(siz==size[ch[x][0]]+1) return x;
        else if(siz<=size[ch[x][0]]) return find2(ch[x][0],siz);
        else return find2(ch[x][1],siz-size[ch[x][0]]-1);
    }
    //操作
    void insert(int &x,int vul,int fa){
        if(x==0){newnode(x,fa,vul);return ;}
        if(key[x]>vul) insert(ch[x][0],vul,x);
        else insert(ch[x][1],vul,x);
        up(x);
    }
    void erase(int vul){
        splay(find1(root,vul),0);int t=size[ch[root][0]]+1;
        splay(find2(root,t-1),0);splay(find2(root,t+1),root);
        pre[rt]=0;rt=0;up(ch[root][1]);up(root);
    }
    void rank1(int vul){
        splay(find1(root,vul),0);
        printf("%d
    ",size[ch[root][0]]);
    }
    void frank(int x){
        printf("%d
    ",key[find2(root,x+1)]);
    }
    int ans;
    void vul_pre(int x,int vul){
        if(!x) return ;
        if(key[x]>=vul) vul_pre(ch[x][0],vul);
        else{
            int t=vul-key[x];
            if(t<=vul-ans) ans=key[x],vul_pre(ch[x][1],vul);
            else vul_pre(ch[x][1],vul);
        }
    }
    void vul_last(int x,int vul){
        if(!x) return ;
        if(key[x]<=vul) vul_last(ch[x][1],vul);
        else{
            int t=key[x]-vul;
            if(t<=ans-vul) ans=key[x],vul_last(ch[x][0],vul);
            else vul_last(ch[x][0],vul);
        }
    }
    void inte(){
        cnt=0;
        newnode(root,0,-1*inf);
        newnode(ch[root][1],root,inf);
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("3.out","w",stdout);
        int n;scanf("%d",&n);
        int op,vul;
        inte();
        for(int i=1;i<=n;i++){
            scanf("%d%d",&op,&vul);
            if(op==1) insert(root,vul,0);
            else if(op==2) erase(vul);
            else if(op==3) rank1(vul);
            else if(op==4) frank(vul);
            else if(op==5){
                ans=-1*inf;vul_pre(root,vul);
                printf("%d
    ",ans);
            }
            else{
                ans=inf;vul_last(root,vul);
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 21834  Solved: 9749
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000
    2.每个数的数据范围:[-2e9,2e9]
  • 相关阅读:
    重新整理数据结构与算法(c#)——算法套路迪杰斯特拉算法[三十一]
    重新整理数据结构与算法(c#)——算法套路k克鲁斯算法[三十]
    重新整理数据结构与算法(c#)——算法套路普利姆算法[二十九]
    arp 的概念解析
    什么是ip协议二
    什么是ip协议一
    python自动化报告的输出
    使用wxpy自动发送微信消息
    Pycharm2017常用快捷键
    【新番】不正经的魔术讲师与禁忌教典【全集更新中】
  • 原文地址:https://www.cnblogs.com/wang9897/p/9477731.html
Copyright © 2020-2023  润新知