[关闭]
@Dmaxiya 2026-09-01T13:01:33.000000Z 字数 2424 阅读 13

Codeforces 2258 B2 题解(临时文档)

Codeforces


题目大意

给定 根胡萝卜,长度分别为 )。
有一台切割机,每次操作可以同时选择任意多根胡萝卜(已切出的也可以再选),并对每根被选的胡萝卜执行:若其长度 则不变,否则切成 两段( 为正整数,每次操作可不同)。

对于每个 ,问恰好使用 次操作后,最多能选出多少根长度完全相同的胡萝卜(所有选出的长度必须一致)。
每个 独立求解,互不影响。


核心观察

1. 固定目标长度 时的最优切割策略

若我们希望最终得到尽量多长度为 的胡萝卜,那么对于每一根原始胡萝卜,最优的切割顺序是从大到小切:

即第一刀先切出 的块(如果原长度足够),第二刀切 ,依此类推。这样能保证在 刀内获得尽可能多的 小块。


2. 单根胡萝卜对固定 的贡献公式

设当前操作次数为 ,目标长度为 。令:

对于某一根长度为 的胡萝卜:

解释
- 是长度 理论上最多能包含的 的个数。
- 但由于只有 次切割,最多只能切出 个完整的 小块(因为要得到 个整块需要恰好的整除条件,否则缺一刀)。
- 两者取小即为实际贡献。


3. 最优 的取值范围

固定时,若目标长度 太大,使得 ,则没有任何胡萝卜能触发“特殊贡献”,且所有 都会很小甚至为 0,答案必然劣于取更小的
因此最优解只需要考虑:

,则唯一有用的 ,且此时答案就是所有胡萝卜长度之和(因为全部切成 1)。


快速计算方法(困难版的关键优化)

如果直接枚举每个 和每个 ,再对 根胡萝卜求和,复杂度为 ,不可接受。
我们需要利用长度值域 前缀和来加速。

预处理

则任意区间 内的胡萝卜总数可在 得到:


固定 时,使用分段求和

对于固定的 ,将所有胡萝卜按 的值分组。
,则 相同的胡萝卜长度落在区间:

这些胡萝卜的数量可以直接用前缀和求出:

这一组对总答案的贡献为:

我们将 全部累加,就得到了常规部分的总贡献。


处理特殊情况

当存在长度为 的胡萝卜时,这些胡萝卜在常规部分被算作 ,贡献为 ,少算了
因此需要额外加上:

(仅当 时存在)


总复杂度分析

对于固定的 ,内层循环次数为
有效的 范围是 ,且

对所有 求和:

时,,实际运行效率完全可行,题解中记为 (将对数平方视作小常数)。

预处理 需要 ,总复杂度满足题目限制。


正确性证明概要

  1. 切割顺序最优性
    每次切出当前最大可获得的 块,保证在 次内最大化 小块数量,这是贪心最优(可通过归纳证明)。

  2. 贡献公式的正确性
    对任意长度 ,它至多包含 ,且 次切割最多产生 个完整小块(除非正好整除产生 个)。公式精确刻画了这两种情况。

  3. 枚举范围的正确性
    ,则 ,没有任何胡萝卜能贡献 ,且所有 或很小,答案不会超过取 的情况,因此可忽略。

  4. 分段求和正确性
    将所有胡萝卜按 分组,同组贡献相同,利用前缀和统计数量,结果等价于逐项累加。


注意事项

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注