1 条题解
-
0
题解
题意简述
给定 ,满足 。定义 为对序列 进行至多 次“删除长为 的连续子数组”操作后,可能得到的序列的 的最小值。要求构造一个长为 的序列 (元素在 ),使 最大。
思路分析
1. 基本观察
- 删除操作不会增加 ,所以最多 次等价于恰好 次(可以补空操作)。
- 最终序列长度 。
- 显然 ,因此:
2. 考虑每个数字的出现次数
若我们想让 ,那么 必须都在最终序列中出现。
每次删除最多能去掉每个数字的一个出现(因为删除的是连续段,但一个数字可能在不同位置出现多次)。
因此,若某个数字在原始序列中出现 次,则它在最终序列中至少还有 次(因为一次删除至多删掉一个该数字)。为了让 在最终序列中至少出现一次,每个这样的数字必须满足:
否则可能被 次删除全部删光。
因此,在原始序列中, 必须各出现至少 次。
$$n \ge (m+1) \cdot x \quad \Rightarrow \quad x \le \frac{n}{m+1} $$
总长度要求:所以:
3. 综合上界
由以上两点:
$$f(a) \le \min\left(n - m \cdot k,\ \left\lfloor \frac{n}{m+1} \right\rfloor\right) $$我们声称这个上界可达,即:
$$f_{\max} = \min\left(n - m \cdot k,\ \left\lfloor \frac{n}{m+1} \right\rfloor\right) $$
4. 构造证明
分两种情况:
情况 1:
$$n - m \cdot k < \frac{n}{m+1} \quad\Rightarrow\quad n - \frac{n}{m+1} < m \cdot k $$$$\frac{(m+1)n - n}{m+1} = \frac{m n}{m+1} < m \cdot k \quad\Rightarrow\quad \frac{n}{m+1} < k $$
即 。整理得:此时 ,即最终长度小于 。
构造:(即 循环)。
由于 ,最终剩余的部分必然严格递增 (因为循环周期 且 大于剩余长度)。
无论删哪 个长为 的段,剩余部分形如连续的一串 且长度为 ,其 就是该长度(即 )。
因此 ,达到上界中较小的那个。
情况 2:否则,即 ,但注意 可能小于等于 。此时最大 由 决定。
构造:设 。取:
这样 每个数出现次数:
- 如果 ,则前 个数出现 次,其余 个数出现 次。
- 因为 (根据 得 ),所以每个 至少出现 次(前 个出现更多)。
此外,相同数字的间隔至少为 (因为 且 在情况 2 中成立)。
因此,每次删除一个长为 的段最多只能删掉每个数字的一个副本。经过 次删除,每个 至少剩余一次,所以最终 。又因为最终长度 (情况 2 的前提),所以 可达。因此 。
算法实现
按上述构造,一行判断:
- 若 ,取模 ;
- 否则取模 。
时间复杂度 打印。
代码
#include <bits/stdc++.h> using namespace std; int main() { int T; cin >> T; while (T--) { int n, m, k; cin >> n >> m >> k; int mod = (n < (m + 1) * k) ? k : n / (m + 1); for (int i = 0; i < n; ++i) { cout << i % mod << " \n"[i == n - 1]; } } return 0; }
- 1
信息
- ID
- 7037
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者