P15681 分糖果 题解

· · 题解

我们注意到,对于每组询问 m,k ,使得前 x 个篮子中的糖果个数恰为 k 个的充要条件为,存在一种放置方案使得前 x 个篮子中的糖果个数都不少于 k 个,也存在一种放置方案使得前 x 个篮子中的糖果个数都不多于 k 个。因为如果达到了其中一种状态,则通过逐个糖果的调整,一定能到达前 x 个篮子中的糖果个数恰为 k 个的中间状态。

考虑二分答案,设当前二分值为 x ,对于第一个条件,为了使得前 x 个篮子中的糖果个数都大于等于 k 个,我们应尽量向前 x 个篮子中放置,并在前 x 个篮子中尽量平均地放置。具体的,对于每一个 a_{i},若 a_{i}\gt x 则在前 x 个篮子中各放一个,否则,选择目前拥有糖果数最少的 a_i 个篮子分别放一个。任意时刻任意两个篮子中糖果个数差一定不超过 1 ,故只需判断最终前 x 个篮子中的糖果数是否不少于 k \times x 即可。对于第二个条件,我们应尽量不向前 x 个篮子中放置,并在前 x 个篮子中尽量平均地放置。具体放置方法同理,若 a_{i}\le m-x 则在后 m-x 个篮子中放,否则,现在后面的 m-x 个篮子中分别放一个,再将剩下的选择目前拥有糖果数最少的 a_i 个篮子分别放一个。

上述两个条件写成式子则为:

在每次二分中利用树状数组查询区间数个数与区间和可以做到小常数 O(n \log^2n),或在值域线段树上分别对第一个条件与第二个条件二分,取较小值作为答案,可以做到 O(n \log n)