zoukankan      html  css  js  c++  java
  • 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语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/wang9897/p/9477731.html
Copyright © 2011-2022 走看看