• AcWing 244. 谜一样的牛 (树状数组+二分)打卡


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

    题意:有n只牛,现在他们按一种顺序排好,现在知道每只牛前面有几只牛比自己低,牛的身高是1-n,现在求每只牛的身高

    思路:我们可以考虑最后一只牛,最后一只牛前面比他低的有 a[n]只,那么他的身高就是 a[n]+1

    假设这只取的是  1   ,倒数第二只牛  a[n-1]=1  ,说明前面有一只比他低,但是他不能直接取2,因为后面已经取了1,但是前面还有比他低的,说明每一步只能是在现有没被选的中选a[i]+1大的身高,然后确定身高的话我们用一个数组b[i],代表这个是否被选,为了方便树状数组取值,我初值都设为1,然后树状数组取前缀和就是代表比当前身高低的个数,然后我们二分找身高即可

    #include<bits/stdc++.h>
    #define maxn 100005
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    ll n,a[maxn],b[maxn],c[maxn];
    ll lowbit(ll x){
        return x&(-x);
    }
    void add(ll x,ll y){
        while(x<=n){
            c[x]+=y;
            x+=lowbit(x);
        }
    }
    ll query(ll x){
        ll sum=0;
        while(x){
            sum+=c[x];
            x-=lowbit(x);
        }
        return sum;
    }
    int main(){
        scanf("%lld",&n);
        for(int i=1;i<=n;i++){
            b[i]=1;
            add(i,1);
        }
        for(int i=2;i<=n;i++) scanf("%lld",&a[i]);
        for(int i=n;i>=2;i--){
            ll l=0,r=n+1,ans;
            while(l<r){
                ll mid=(l+r)/2;
                if(query(mid)>=a[i]+1){
                    ans=mid;
                    r=mid;
                } 
                else l=mid+1;
            } 
            a[i]=ans;
            b[ans]=0;
            add(ans,-1);
        }
        for(int i=1;i<=n;i++){
            if(b[i]){
                printf("%lld
    ",i);
                break;
            }
        }
        for(int i=2;i<=n;i++){
            printf("%lld
    ",a[i]);
        }
    }
     
  • 相关阅读:
    HTML表单
    CSS等高布局的6种方式
    HTML用户反馈表单
    HTML美化修饰<A>
    sql查询语句 --------一个表中的字段对应另外一个表中的两个字段的查询语句
    jq 表格添加删除行
    js 静止f1到f12 和屏蔽鼠标右键
    手机自适应页面的meta标签
    tp3.2 的验证码的使用
    php多线程抓取网页
  • 原文地址:https://www.cnblogs.com/Lis-/p/11309763.html
Copyright © 2020-2023  润新知