CF1244E

发布时间 2024-01-11 10:21:56作者: C01et10n

CF1244E Minimizing Difference 题解

Codeforces


闲话

吐槽一下,ABC330F 比此题严格更强,但是它评了绿,这题评了蓝。(个人感觉大概都是绿。)


题解

给你一个序列 \(a_i\),一次操作将一个数的值增加 \(\pm1\),进行至多 \(k\) 次操作后,求最小 \(\max\{a_i\} - \min\{a_i\}\)

把序列抽象成一个数轴,其上 \(n\) 个点,第 \(i\) 个点的坐标是 \(a_i\),一次操作将一个点左移或右移 \(1\) 单位,至多 \(k\) 次操作后,用一条线段盖住所有点,求线段最小长度。

结论

  • 为了使线段的位置最优(操作次数少),它必然有一端在一个点上。

证明

能感性理解的话可跳过

注意:以下“包含”、“盖住”指严格包含(在端点上不算包含)。

比如:

将黑色线段左移,其端点刚好碰到一个点时,停下,记为红线。右移,同样碰到点就停下,记为蓝线。(也就是说,它快要盖住或离开一个点时,停止移动。)

这个结论就是,黑色线段 不优于红线 或 不优于蓝线。

因为像我们这样移动黑线,并不会改变任何点的被包含状态(线段不会覆盖任何点,也不会离开任何点)。

左移线段 \(x\) 单位(\(x\) 可为负,即右移),会使右边没被盖住的点代价增加 \(x\),左边没被盖住的点代价减少 \(x\)

那么,如果左边点多,向左移(红线);右边点多,向右移(蓝线)。这样,红蓝线里必然有一个不劣于黑色。证毕。

这样,没有端点在点上的线段(黑线),都不优于端点在点上的线段(红/蓝线)。那么这些黑线就不用考虑了。

做法

容易想到,短的线段可以覆盖,长的必然也可以。问题单调,考虑二分线段长。

如何 check(x)

由上面的结论,线段一定有一端在点上。那就可以 \(O(n)\) 枚举线段位置,每个点两种情况:线段的左/右端点在它这里。

考虑快速统计一个位置的代价。前缀和维护坐标和即可 \(O(\log n)\)

复杂度 \(O(n \log n \cdot \log V)\)\(V\) 是坐标值域。

Submission


题外话:ABC330F 题解

这个东西转成二维了,但是其实它的 \(x\)\(y\) 是分开的,因为是曼哈顿距离。所以 \(x\)\(y\) 分别排序,共用 \(k\) 的贡献即可。

复杂度还是 \(O(n \log n\cdot\log V)\)\(V\) 为坐标值域。

Submission