2024.12.30 周一
Q1. 1100
Farmer John has a permutation $p_1, p_2, \ldots, p_n$, where every integer from $0$ to $n-1$ occurs exactly once. He gives Bessie an array $a$ of length $n$ and challenges her to construct $p$ based on $a$.
The array $a$ is constructed so that $a_i$ = $\texttt{MEX}(p_1, p_2, \ldots, p_i) - p_i$, where the $\texttt{MEX}$ of an array is the minimum non-negative integer that does not appear in that array. For example, $\texttt{MEX}(1, 2, 3) = 0$ and $\texttt{MEX}(3, 1, 0) = 2$.
Help Bessie construct any valid permutation $p$ that satisfies $a$. The input is given in such a way that at least one valid $p$ exists. If there are multiple possible $p$, it is enough to print one of them.
Input
It is guaranteed that there is at least one valid $p$ for the given data.
------------------------独自思考分割线------------------------
-
MEX函数的三种思考方向:加数会变/不变,反向考虑去数能够 $O(1)$ 找到值。
A1.
- 对MEX函数向集合加数只需要考虑2个方向:MEX变/不变。一种方案是先考虑不变,不合法再考虑变。
- 第一次写这道题是在12.11,一直T16,当时是先考虑变,这样的话找更新值的时候会T。
- 这样做是过了,但是很难证明是对的。
- 正解时从后向前构造,这样有制约关系,就一定是对的。
------------------------代码分割线------------------------
A1.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' // 交互/调试 关
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
void _();
signed main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cout << fixed << setprecision(6);int T = 1;cin >> T;while (T--)_();return 0;
}void _()
{int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i++)cin >> a[i];vector<int> st(n + 1);int mex = 0;auto find = [&](){while (st[mex])mex++;};for (int i = 1; i <= n; i++){int p = mex - a[i];if (p >= 0 && p < n && !st[p])st[p] = 1;else{p = mex;st[p] = 1;find();}// bug2(i, mex);cout << p << ' ';}cout << endl;
}