https://codeforces.com/contest/1330/problem/C

题意:

\(n\) 个无色的格子和 \(m\) 个数字 \(l_i\) 。进行 \(m\) 次操作,每次选择一个正整数 \(p_i\) ,把从 \(p_i\) 开始的 \(l_i\) 个格子染成第 \(i\) 种颜色。如果一个格子被多次染色就只取最后的颜色。要求最后所有的格子有色,且每种颜色都存在。输出 \(p_1,p_2,\cdots p_n\) ,若无解输出 \(-1\)
要求最后所有颜色都要有,仅仅过程中出现过不行

思路:

先考虑什么情况下没有解。如果所有 \(l\) 的和小于 \(n\) ,显然无解。在第 \(i\) 次染色之前,至少有 \(i-1\) 个格子已经被染色,那么这次最多只能染 \(n-(i-1)\) 个,如果 \(l_i>n-(i-1)\) ,就会干掉之前的某几种颜色,不符合题意。

考虑贪心染色,让每个 \(p_i\) 尽量小,同时要保证后面的 \(l_i\) 加起来大于未染色的格子数,即 \(p_i=max(i,n+1-\Sigma_{j=i}^n l_i)\)

#include <bits/stdc++.h>
using namespace std;
#define QUIT {puts("-1");return 0; }

const int N = 1e5+10;
long long l[N];

signed main()
{
    long long n, m; cin >> n >> m;
    long long tot = 0;
    for(int i = 1; i <= m; i++)
    {
        cin >> l[i];
        if(l[i] > n-i+1) QUIT
        tot += l[i];
    }
    if(tot < n) QUIT
    for(int i = m; i >= 1; i--)
       l[i] += l[i+1];
    for(int i = 1; i <= m; i++)
        cout << max(1ll*i, n + 1 - l[i]) << ' ';

    return 0;
}