• AcWing 244. 谜一样的牛|树状数组


    传送门

    题目描述

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

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

    输入格式

    第1行:输入整数n。

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

    输出格式

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

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

    数据范围

    1n105

    输入样例:

    5
    1
    2
    1
    0
    

    输出样例:

    2
    4
    5
    3
    1

    题解:如果最后一头牛前面有An头牛比它矮显然它的身高为An+1。如果倒数第二头牛前面有An-1头牛比它矮的话它的身高为1~n里面除了最后一头牛的身高以外第An-1+1大的值。以此类推我们知道第i头牛它的身高是1~n中除了第i+1到n以外的值中第Ai+1大的值。

       我们可以建立一个长度为n的01序列,从n到1倒序找出第Ai+1个1的位置作为第i头牛的身高,然后将这个位置的1变为0。

       我们可以用树状数组来维护前x个中有多少个1,先将每个位置都add(1),如果数量和Ai+1一样那么这个x就是第i头牛的身高,再将这个位置减去add(-1)。

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int INF = 2e9;
    const int N = 1e5 + 10;
    int a[N],sum[N],ans[N];
    int lowbit(int x) { return x&(-x);}
    void add(int x,int y) {
        for (;x<N;x+=lowbit(x)) sum[x]+=y;
    }
    int query(int x) {
        int ans = 0;
        for (;x>0;x-=lowbit(x)) ans += sum[x];
        return ans;
    }
    int main() {
        int n;
        scanf("%d",&n);
        a[1] = 1;
        add(1,1);
        for (int i = 2; i <= n; i++) {
            scanf("%d",&a[i]);
            a[i]++;
            add(i,1);
        }
        for (int i = n; i > 0; --i) {
            int l = 1,r = n,mid;
            while (l<r) {
                mid = (l+r)/2;
                if (query(mid) >= a[i]) r = mid;
                else l = mid+1;
            }
            ans[i] = l;
            add(l,-1);
        }
        for (int i = 1; i <= n; i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
    View Code

      

  • 相关阅读:
    mac下卸载mysql
    mac安装MySQL笔记
    mac安装python3.7.0
    web自动化测试之8大元素定位方法
    postman的下载和使用
    说说性能测试
    jmeter动态修改线程组参数
    服务器性能监控
    性能测试分配堆内存
    nmon分析工具的使用
  • 原文地址:https://www.cnblogs.com/l999q/p/11348580.html
Copyright © 2020-2023  润新知