1 条题解

  • 0
    @ 2026-8-30 10:58:29

    题解

    思路

    设选择的区间内,某个原值 x≠cx\ne c 通过加上 k=c−xk=c-x 变成 cc。区间内每个等于 xx 的位置贡献 +1+1,而原本等于 cc 的位置会被改走,贡献 −1-1;其他位置贡献 00。

    因此答案等于原序列中 cc 的个数,加上对某个 x≠cx\ne c 的 +1/−1/0+1/-1/0 序列的最大子段和。

    做法

    子任务 1:枚举目标值与区间

    n≤20n\le20 时,枚举序列中出现的 x≠cx\ne c 以及所有 [l,r][l,r],直接计算净增量。

    子任务 2:逐值运行 Kadane

    n≤2000n\le2000 时,对每个不同的 x≠cx\ne c 扫描整个数组:ai=xa_i=x 时权值为 11,ai=ca_i=c 时为 −1-1,否则为 00。用 Kadane 算法求最大子段和。复杂度为 O(nV)O(nV),其中 VV 是不同值数量,最坏为 O(n2)O(n^2)。

    子任务 3:按值维护线性 DP

    从左向右扫描。令 countC 为已经遇到的 cc 数量。对每个值 x≠cx\ne c,维护以它最近一次出现为右端点的最大净增量 best[x],以及它上次出现时的 countC。

    再次遇到 xx 时,若延续原区间,需要减去两次出现之间新增的 cc 数量,再加上本次的 11;也可以从当前位置重新开始:

    bestx=max⁡(1,bestx+1−(countC−lastCx)).best_x=\max(1,best_x+1-(countC-lastC_x)).

    所有值的最大 best 就是最多新增数量。

    正确性证明

    引理 1

    固定 x≠cx\ne c 后,对区间加上 c−xc-x 的净增量等于区间内 xx 的个数减去 cc 的个数。

    证明:区间内的 xx 全部变成 cc,各新增一个;原有 cc 因加上非零数而不再等于 cc,各损失一个;其他值既不是 xx 也不会变成 cc。证毕。

    引理 2

    对固定 xx,最优操作的净增量是对应 +1/−1/0+1/-1/0 序列的最大子段和。

    证明:每个可选区间与该序列的一个连续子段一一对应,由引理 1,其子段和恰为操作净增量。证毕。

    引理 3

    线性 DP 更新后,best[x] 是以当前 xx 位置结尾的最大净增量。

    证明:一个最优子段要么从当前 xx 重新开始,值为 11;要么延续到上一次 xx 结尾的最优子段,中间只有新出现的 cc 会降低净增量,再加入当前 xx 的贡献 11。转移恰取二者最大。证毕。

    定理

    算法输出操作后 cc 的最大频率。

    证明:由引理 2,枚举全部 xx 的最大子段和覆盖所有非零操作;引理 3 保证线性 DP 准确求得这些最大值。再加上原有 cc 数量,并允许净增量为 00,即得到全局最优。证毕。

    复杂度

    满分算法时间复杂度为 O(n)O(n),空间复杂度为 O(max⁡ai)O(\max a_i)。

    • 1

    信息

    ID
    1182
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    0
    上传者