zoukankan      html  css  js  c++  java
  • AcWing244谜一样的牛(树状数组+二分)

    题目地址https://www.acwing.com/problem/content/245/

    题目描述

    有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高。

    现在这n头奶牛站成一列,已知第i头牛前面有AiAi头牛比它低,求每头奶牛的身高。

    输入格式

    第1行:输入整数n。

    第2..n行:每行输入一个整数AiAi,第i行表示第i头牛前面有AiAi头牛比它低。
    (注意:因为第1头牛前面没有牛,所以并没有将它列出)

    输出格式

    输出包含n行,每行输出一个整数表示牛的身高。

    第i行输出第i头牛的身高。

    数据范围

    1n1e5

    题解:这道题需要从后往前考虑。需要完成两个问题:找到剩余最小的第k个数、删除一个数。本来这是典型的平衡树问题,但是一般而言的平衡树比较难写。而且对于这道题而言,可以使用树状数组+二分来完成。可以让每个a[i]=1,然后查找第一个前缀和大于给出的值,就是当前结果,至于删除一个数,就是让这个数的位置加上-1就可以了。

    AC代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=1e5+10;
    #define lowbit(x) (x&(-x))
    int c[N],n;
    int b[N];
    int a[N];
    
    void add(int x,int d){
        while(x<=n){
            c[x]+=d;
            x+=lowbit(x);
        }
    } 
    
    int sum(int x){
        int sum=0;
        while(x>0){
            sum+=c[x];
            x-=lowbit(x);
        }
        return sum;
    }
    
    int main(){
        cin>>n;
        memset(c,0,sizeof(c));
        for(int i=2;i<=n;i++) cin>>b[i];
        for(int i=1;i<=n;i++) add(i,1);
        b[1]=0;
        for(int i=n;i>=1;i--){
            int l=1,r=n;
            while(l<r){
                int mid=l+r>>1;
                if(sum(mid)>b[i]) r=mid;
                else l=mid+1; 
            }
            a[i]=r;
            add(r,-1);
        } 
        for(int i=1;i<=n;i++) cout<<a[i]<<endl; 
        return 0;
    }

    写于:2020/8/26 23:16


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    终端字符颜色、样式控制
    popen——php多进程利器
    游戏技能效果与buff设定
    Linux 记录服务器负载、内存、cpu状态的PHP脚本
    简单的,省份和城市选择,非ajax版
    一道js题目
    左右结构,右边上固定、下iframe,iframe自动改变大小
    mysql 忘记root密码
    socket 学习(转载)
    子页面关闭后,更新父页面
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13568703.html
Copyright © 2011-2022 走看看