NC51101 Lost Cows

科技资讯 投稿 5400 0 评论

NC51101 Lost Cows

题目

题目描述

Regrettably, FJ does not have a way to sort them. Furthermore, he's not very good at observing problems. Instead of writing down each cow's brand, he determined a rather silly statistic: For each cow in line, he knows the number of cows that precede that cow in line that do, in fact, have smaller brands than that cow。

输入描述

    Line 1: A single integer, N
  • Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed. Line 2 of the input describes the number of preceding cows whose brands are smaller than the cow in slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in slot #3; and so on.

输出描述

    Lines 1..N: Each of the N lines of output tells the brand of a cow in line. Line #1 of the output tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.

示例1

输入

5
1
2
1
0

输出

2
4
5
3
1

题解

知识点:树状数组,倍增,枚举。

首先用树状数组维护右侧出现的数字,随后需要二分一个 \(x\ 通过比较 \(x - cnt_{<x} -1 < a_i\ 得知 \(x\ 是否小了还是大了,从而找到第一个 \(x - cnt_{<x} -1 = a_i\ 的点。注意,条件不能为 \(x - cnt_{<x} -1 \leq a_i\,因为可能会出现连续一段刚好等于 \(a_i\ 的点,而我们只需要第一个的下标即可,如果用这个条件,我们得到的是最后一个下标。

另外,二分套树状数组查询的复杂度是对数平方的,并不是最优的。我们可以直接使用树状数组本身的倍增性质进行二分,是最优的对数复杂度。我封装了两个常用的函数,大于等于 lower_bound 和大于 upper_bound

lower_bound 查询即可。

空间复杂度 \(O(n\

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

template <class T>
class Fenwick {
    int n;
    vector<T> node;

public:
    Fenwick(int _n = 0 { init(_n; }

    void init(int _n {
        n = _n;
        node.assign(n + 1, T(;
    }

    void update(int x, T val { for (int i = x;i <= n;i += i & -i node[i] += val; }

    T query(int x {
        T ans = T(;
        for (int i = x;i >= 1;i -= i & -i ans += node[i];
        return ans;
    }
    T query(int l, int r { return query(r - query(l - 1; }

    int lower_bound(T val {
        int pos = 0;
        for (int i = 1 << __lg(n; i; i >>= 1 {
            if (pos + i <= n && node[pos + i] < val {
                pos += i;
                val -= node[pos];
            }
        }
        return pos + 1;
    }
    int upper_bound(T val {
        int pos = 0;
        for (int i = 1 << __lg(n; i; i >>= 1 {
            if (pos + i <= n && node[pos + i] <= val {
                pos += i;
                val -= node[pos];
            }
        }
        return pos + 1;
    }
};

int a[8007];
int main( {
    std::ios::sync_with_stdio(0, cin.tie(0, cout.tie(0;
    int n;
    cin >> n;
    for (int i = 2;i <= n;i++ cin >> a[i];
    Fenwick<int> fw(n;
    for (int i = 1;i <= n;i++ fw.update(i, 1;

    vector<int> ans(n + 1;
    for (int i = n;i >= 1;i-- {
        ans[i] = fw.lower_bound(a[i] + 1;
        fw.update(ans[i], -1;
    }
    for (int i = 1;i <= n;i++ cout << ans[i] << '\n';
    return 0;
}

编程笔记 » NC51101 Lost Cows

赞同 (25) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽