「CTSC 2013」组合子逻辑

题目大意:给出一个数列 $n$ 个数,一开始有一个括号包含 $[1,n]$,你需要加一些括号,使得每个括号(包括一开始的)所包含的元素个数 $\leq$ 这个括号左端点那个数的大小。当一个括号包含另一个括号时,里面那个括号内所有数整体被看做是一个元素。无解输出 $-1$。$N\leq 2\times 10^6$

(这是谁!!!写的题面!!!(╯‵□′)╯︵┻━┻

$k$ 表示当前的最大值还能再包含多少位,当前的最大值不一定要包含当前位,只要求出正确结果即可。

#include <cstdio>
#include <queue>

int a[2000005];
std::priority_queue<int> Q;

int read() {
    int x = 0; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48);
        c = getchar();
    }
    return x;
}

int main() {
    int T = read();
    while (T--) {
        int n = read();
        if (n == 1) {
            puts(read() ? "0" : "-1");
            continue;
        }
        for (int i = 1; i <= n; ++i) a[i] = read();
        int k = a[1] - 1, ans = 1;
        while (!Q.empty()) Q.pop();
        for (int i = 2; i <= n; ++i) {
            if (k) --k;
            else {
                if (Q.empty() || Q.top() < 2) { ans = -1; break; }
                ++ans, k = Q.top() - 2, Q.pop();
            }
            Q.push(a[i]);
        }
        printf("%d\n", ans);
    }
    return 0;
}