wqs二分的无脑写法

我曾经被 wqs 二分的边界折磨死了。后面听说有种很无脑的写法,听说是 lhx 大神发明的,记录一下。

假设我们要求的是恰好 \(k\) 个的最大值,大概是这样的:

int l = -1e6, r = 1e6;
while (l + 1 < r) {
    int mid = l + r >> 1;
    if (check(mid).se >= k) l = mid;
    else r = mid;
}
return min(check(l).fi + l * k, check(r).fi + r * k);

这个东西很巧妙的地方在于,你不再需要在 check() 里再关心同样结果下是多取还是少取。而且不用再关心 l 是取 mid 还是 mid + 1 的问题了。

好,问题来了,为什么这个是对的?而且这个求的是最大值啊,为什么取 min 是对的?

我们画个图。

假设答案在 Ans 点,我们二分到了 l 在 L,r 在 R,此时我们用 L 算出来的 Ans' 是飞出了答案的凸函数的,而用 R 算出来的是答案。我们发现算出来只可能更大,而且因为是整数所以一定有一个是答案。于是我们取个 min 就好啦。

posted @ 2025-10-20 22:54  Infter  阅读(5)  评论(0)    收藏  举报