1 条题解
-
0
题目理解
我们有一个长度为 的数组 和一个整数 。每次操作可以选择一个元素将其增加 (可以多次对同一元素操作)。目标是最大化数组的 MEX(最小缺失非负整数)。
核心观察:
- 要使 MEX 至少为 ,必须保证 每个数在数组中都至少出现一次。
- 由于只有 个元素,MEX 最大不会超过 (因为要覆盖 到 需要 个不同的数)。
- 我们只能增加元素的值,不能减小。因此初始值大于 的元素对构建 到 没有帮助,可以忽略。
解题思路
1. 频率统计
建立频率数组 ,其中 表示值为 的元素个数。我们只关心 到 的范围(因为 MEX 不会超过 )。
2. 贪心策略
从 开始,依次检查每个数是否出现:
-
如果 :说明 已经存在,我们可以尝试让 MEX 更大。此时如果 (有重复),我们可以保留一个 ,把多余的 个元素通过若干次 操作变成更大的数。由于每次只能加 ,这些元素可以变成 。我们把这些元素计入对应的频率中:。然后将 设为 (只保留一个)。
-
如果 :说明 无法被凑出来,此时 MEX 最大就是 ,停止循环。
3. 为什么这样是对的?
- 我们从小到大处理,保证每个数 在需要时已经存在(要么初始就有,要么由之前的重复元素通过加 得到)。
- 当遇到 时,没有任何办法得到 (因为只能加 ,无法减,而所有小于 的数都已经处理完毕,不会再有新元素变成 )。
- 重复元素提前“升级”到更大的数,为后面可能缺失的数做准备。
4. 时间复杂度
每个测试用例 ,因为只遍历 到 一次,并且每个元素至多被“移动”一次到更大的位置。
示例解析
示例 1
频率统计(只考虑 到 ): $freq[0]=1, freq[1]=1, freq[2]=2, freq[3]=1, freq[4]=0, freq[5]=1, freq[6]=0$
过程:
- :, 无重复 → 继续。
- :,无重复 → 继续。
- :,有重复。保留 个 ,把 个 变成 → ,。现在 。
- :,无重复 → 继续。
- : → 停止。MEX 。
示例 2
频率统计( 到 ): $freq[0]=1, freq[1]=2, freq[2]=1, freq[3]=1, freq[4]=1, freq[5]=0, freq[6]=0$
过程:
- : → 继续。
- :,有重复。保留 个 ,把 个 变成 → ,。
- : → 继续。
- :,有重复。保留 个 ,把 个 变成 → ,。
- : → 继续。
- :,无重复 → 继续。
- : → 停止。MEX 。
示例 3
频率统计( 到 ): $freq[0]=0, freq[1]=0, freq[2]=1, freq[3]=1, freq[4]=0$
过程:
- : → 停止。MEX 。
代码实现要点
def solve(): t = int(input()) for _ in range(t): n, x = map(int, input().split()) a = list(map(int, input().split())) freq = [0] * (n + 1) # 只关心 0 到 n for val in a: if val <= n: freq[val] += 1 for k in range(n + 1): if freq[k] == 0: print(k) break if freq[k] > 1 and k + x <= n: freq[k + x] += freq[k] - 1 freq[k] = 1注意:当 时,多余的重复元素无法帮助构建 到 范围内的数,可以丢弃(因为对提高 MEX 无贡献)。
- 1
信息
- ID
- 6308
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者