给定长为 $N$ 的非负整数数组 $A$。$Q$ 次询问 $K$,将每个 $A_i$ 替换为 $A_i$ 或 $K - A_i$,最大化 $\text{mex}(A')$。
制约:$N \le 5 \times 10^3$,$Q \le 5 \times 10^5$,$0 \le A_i \le 10^9$。
考虑到 $\operatorname{mex} < N$,目标是从小到大依次凑齐 $0 \dots N-1$,任何 $\geqslant N$ 的数都没用。
Approach 1: 按 $K$ 的大小分类
Case.1 $K \ge 2N$
分出这样的情况,是因为此时有很好的性质:
- 对于 $A_{i} < N$,替换后 $K-A_{i}>N$,对凑齐 $0 \dots N-1$ 没有任何作用,因此最佳策略是 保持不变。
- 对于 $A_{i} \geqslant N$,保持不变没用,最佳策略是 替换。
所以每个数的决策都已经确定,下面就是快速计算。
- 对于 1.,与 $K$ 无关,提前预处理。复杂度 $\mathcal{O}(N)$。
- 对于 2.,只需要关注原数组在 $0$ 到 $N-1$ 内缺失的那些数字。依次检查缺失的元素 $x$,判断原数组中是否存在 $K - x$。
2. 的复杂度:在检查 $x$ 时,只有当原数组中存在元素 $v$ 满足 $v = K - x$ 时,检查才会成功。注意其中 $x\in[0, N)$,最多有 $N$ 种可能,$v$ 在原数组中存在,最多有 $N$ 种可能,因此 $(x, v)$ 只有 $N^2$ 种。另外,对于不同的 $K$,$(x, v)$ 不会相同。这意味着在所有的 $Q$ 次查询中,所有检查的总次数不超过 $N^2$。
Case.2 $K < 2N$
这种情况怎么做都可以,因为只有 $\mathcal{O}(N)$ 种 $K$,$\mathcal{O}(N)$ 种需要 check 的数字 $0 \dots N-1$,复杂度是 $\mathcal{O}(N^{2})$。
总时间复杂度为 $O(N^2 + Q)$。
Code(使用 std::unordered_map,可以进一步用双指针优化常数)
Approach 2: 预处理有用的 $K$
通过上述对于 $v = K - x$ 的分析可知,只有 $\mathcal{O}(N)$ 种 $K$ 至少成功检查一次。换言之,只有 $\mathcal{O}(N)$ 种 $K$ 有可能使得原数组的 $\text{mex}$ 变大。
能否直接找到这些 $K$?
- 如果存在一个 $A_{i}$ 使得 $\text{mex} = K - A_{i}$,那么 $K - A_{i}$ 能填上那个空位,能增大原数组的 $\text{mex}$。可以枚举所有 $v = \text{mex} + A_{i}$,用任何线性方法预处理 $K=v$ 的答案。
- 否则,不存在这样的 $A_{i}$,答案为原数组的 $\text{mex}$。
总时间复杂度为 $O(N^2 + Q)$。