wqs二分 学习笔记
Leap_Frog
2020-12-10 17:25:42
## 1. 前言
鸣谢 @$\color{black}\texttt{F}\color{red}\texttt{lying2018}$ 没有他笔者自己就不是很会 wqs二分。
感谢 @$\color{black}\texttt{y}\color{red}\texttt{urzhang}$ 和 @$\color{black}\texttt m\color{red}\texttt{yh}$ 指出日报存在的问题。
看洛谷日报从来没写过 wqs二分 的东西?那只能自力更生了啊。
如果有问题欢迎在评论区留言,应该能做到尽快 upd
~~如果有补充,欢迎在评论区告诉笔者,一起讨论哦~~
其实 wqs二分 本身并不难,但是能否想到 wqs二分 可能才是问题所在。
评论区好像有一群神仙要求输出方案,那就把这个链接放到更醒目的位置吧,[CF125E MST Company 题解连接](https://www.luogu.com.cn/blog/daniu/solution-cf125e)
## 2. 介绍
wqs二分 是神仙 王钦石 在 2012 年论文中提出的一类二分方式。
基本是用来处理一类带有限制的问题的。
比较明显的标志就是 `恰好选 K 个` 等。
使用 wqs二分 有一个前题:原问题具有凹凸性。
举个例子,比如我们的函数是上凸的。
那么根据定义,它的斜率肯定单调递减。
![](https://cdn.luogu.com.cn/upload/image_hosting/22ih2ho5.png)
$$\tiny\text{图片来源于网络}$$
于是,我们可以二分这个斜率,然后快速算出它切这个凸包会切在哪里。
![](https://cdn.luogu.com.cn/upload/image_hosting/rs8witm2.png)
$$\tiny\text{图片来源于网络}$$
注意这个切点 $(x,F(x))$ 的意义:它表示当选 $x$ 个时答案时 $F(x)$
根据凹凸性,这个 $x$ 的大小是随着函数的斜率单调递增/递减的。
因为具有单调性,所以肯定可以用二分。
而二分斜率这类二分就被人们称为 wqs二分。
## 3. 感性理解
感性理解就是有两类物品,二分差值(可以为负)。
如果差值大,那么其中一类物品会少,另一类会多。
然后根据物品数目来决定差值应该减少还是增大。
## 4. 具体实现
笔者刚开始提到的例子,要在一些物品中选择 $K$ 个物品,带有限制
### Part1. 凹凸性
这类题目基本都具有凹凸性。
如果你要选第一个物品,第一次肯定会选当前能选择的最大值。
证明:首先,因为选择之后,限制肯定更严。
如果第二次选择物品价值的比第一次大。
因为第一次限制比第二次小,所以在第一次选择的时候肯定也可以选择第二次的。
与第一次选择了最优价值矛盾。
所以我们证明了 $F(K)-F(K-1)\le F(K+1)-F(K)$。
所以函数 $y=F(K)$ 是凸函数。
### Part2. 求被切点
当前,我们二分到了一个斜率。
我们考虑一下这个函数的意义。
它的横坐标($x$)表示的是当前选了几个物体。
假设斜率为 $k$,那么 $y=kx+b$。
那么上面的式子中,$kx$ 就代表对每个目标物体会增加一定量的代价。
那么我们就直接对每个目标物体减去一定代价,再用贪心、dp等方式求出最优选择物体数量。
这里的 dp 不仅需要求出最小值,还需要求出取到最小值时所选物体数量。
然后就好了?
### Part3. 主体
一个二分就好了,详见下面例题。
### Part4. 注意点
二分结束后,我们只知道最优的斜率。
我们得带入给定的 $K$ 来计算出最优的 $F(x)$。
比如在这个函数关系中,有 $(x_1,F(x_1)),(K,F(K))$ 两个点,它们的斜率等于最优斜率。
那我们拿直线去切函数时可能切到的不是 $(K,F(K))$ 而是 $(x_1,F(x_1))$。
所以直接输出二分到的位置是错误的,必须找到用二分斜率算出的 $F(K)$。
## 5. 应用
1. 可以用来优化一些特殊的费用流模型(下文
2. ~~降维打击~~有一些 dp 需要记录当前选了几个数,如果用 wqs二分 可以把数量维压缩
## 6. 和费用流的关系
wqs二分 经常用来优化费用流模型,所以单独拿来讲一下。
下面的证明是基于费用流算法证明的,如果不会,可略过。
我们假设每次增广流量为 1 的流。
首先,我们思考一下每次增广会做什么。
我们会找到一条从 `s` 到 `t` 的最短路,然后增广它。
而增广过程中,只会使正向图的一些边容量减少。
所以如果一条路径在第 $k$ 次增广时存在,那它肯定在 $\forall i\in[1,k)$,这条路径肯定存在。
所以假设 $\exists i\le j$ 使第 $i$ 次增广时最短路的长度 $>$ 第 $j$ 次的最短路。
因上所述,第 $i$ 次增广使肯定存在第 $j$ 次时的最短路。
所以第 $i$ 次增广的肯定不是残量网络中的最短路,与假设矛盾。
于是我们说明了 $\forall i\le j$,第 $i$ 次增广的最短路 $\le$ 第 $j$ 增广的最短路。
而每次累加上的流量就是这条最短路的长度乘上流量,就等于最短路。
设我们增广 $x$ 次获得的流量是 $f(x)$。
那么 $f(x+1)-f(x)$ 就代表当前残量网络上的最短路。
而上面又说明了残量网络上最短路不减。
所以费用流增广的次数和增广总流量形成的关系肯定是下凸函数。
所以如果多次增广的费用流问题,我们可以用 wqs二分 来优化。
## 7. 例题
补上了几道 wqs二分 题目的证明。
### [P5633最小度限制生成树](https://www.luogu.com.cn/problem/P5633)
例题,顺便补充证明 wqs二分 凸性质。
**题意简叙**:求最小的生成树使点 `s` 度为 $K$。
**题意分析**:
第一类物品是 `s` 的度,第二类物品是其他未和 `s` 连边的边。
随着和 `s` 度增加,我们需要在第一类物品中找到一条最短的边和 `s` 相连。
根据树的环路性质,我们需要把新加入边的两端点形成的路径中最长边断掉。
每次增加/减少的贡献就是第二类物品中的最大值减去第一类物品中的最小值。
因为每次会删去最小值/最大值,所以最小值单调递增,最大值单调递减。
所以每次增加/减少的贡献单调递减。
也就是说原函数的斜率单调递减,我们就证明了此题具有凸性质。
**解题方式**:
凸性质得到了,那么直接上 wqs二分。
每次判定对于和 `s` 相连的边跑一遍最小生成树。
由上文,我们每次直接对和 `s` 有关的边权值加上当前二分的 `mid`。
然后在按照权值排序之后的边序列上选边,做 `Kruskal`。
判断有几条边和 `s` 相连,直接根据这个数量继续二分就好了。
小 tips:每次二分需要求一个 `Kruskal`,但是我们并不需要对于每次二分重新排序边。
我们只需要刚开始排序一遍,对于每次二分直接归并一下就好了。
于是,成功把复杂度从 $O(n\log n\log V)$ 降至 $O(n(\log n+\log V))$
[代码](https://paste.ubuntu.com/p/rmkqqHfCth/)
加强版:[CF125E MST Company](https://www.luogu.com.cn/problem/CF125E),[题解连接](https://www.luogu.com.cn/blog/daniu/solution-cf125e)
### [P2619【国家集训队2】Tree I](https://www.luogu.com.cn/problem/P2619)
这是 wqs二分 发明者在论文中举出的例题。
**题意简述**:一张分白边和黑边的图,求满足白边数量为 $K$ 生成树中最小的。
**题意分析**:
同样分黑白考虑。
如果两点之间没有黑边,我们假设连了一条权值为 $+\infty$ 的黑边。
然后找出黑边形成的最小生成树。
每次加入一条最小的白边,删除一条可以删的最大的黑边,所以也具有凸性质。
而根据 环路性质 以及 `Kruskal` 算法的证明,这样得到的生成树肯定是最优的。
所以此题具有凸性质。
**解题方式**:
和上题类似,二分权值,白边所有边权加上权值。
然后做 MST,求白边选了多少条,然后继续二分。
[代码](https://paste.ubuntu.com/p/6yfgn7MdKq/)
### [CF739E Gosha is hunting](https://www.luogu.com.cn/problem/CF739E)
二维 wqs 二分,~~虽然可以费用流。~~(官方题解还是类似模拟费用流?
首先,这题可以费用流(具体见题解区),而它也刚好是选 $K$ 个的题目。
而费用流的凸性质在上文证明过了,在此不证。
不过,需要注意的是,是费用流模型具有凸性质,而不是费用流的每个部分都具有凸性质。
在此题中表现为是 $a$ 和 $b$ 两维综合起来后具有凸性质。
而不是 $a$ 和 $b$ 两维同时具有凸性质。
因为费用流模型具有凸性质,所以我们可以推出 $a$ 维具有凸性质。
那么我们在二分的时候需要 wqs二分 $a$ 维,然后暴力 dp $b$ 维。
这样才能证明正确性。
~~不过两维都 wqs二分 好像也能正确,也能 AC 此题。~~
代码不贴了,因为笔者写这题时 Too Naive,写的 wqs二分 套 wqs二分。
## 8. 习题
无 wqs二分 正确性证明,请读者自证。
### [CF802O April Fools' Problem (hard)](https://www.luogu.com.cn/problem/CF802O)
~~这题不是愚人节啊。。。~~
首先,这题是取 K 个东西的问题,可以 wqs二分。
我们假设每次打印为物体。
对于当前一个物体,我们有三种选择。
1. 跳过它,不使用它
2. 把它当作一个准备日
3. 把它和之前最小的 a 匹配,并打印
我们可以用优先队列来维护这个过程。
[代码(有注释](https://paste.ubuntu.com/p/YfwcyWN2Gy/)
### [P4983 忘情](https://www.luogu.com.cn/problem/P4983)
首先,分子分母同时除以 $\overline{x}$,然后式子就变成了 $\left(\sum_{i=1}^nx_i\right)+1$。
显然可以前缀和,得到 $S_i-S_{j-1}+1$。
~~此时我们可以斜率优化~~,而仅斜率优化也无法完成这个问题。
毕竟状态至少要两位,复杂度直接变成 $O(n\times m)$
这时候,我们就可以使用 wqs二分 的~~降维打击~~优化状态数功能。
也就是我们对于所选每段值强行加上一个权值,然后把选择数量去掉。
在我们 dp 时,我们还需要记录最优决策选择的区间数量,方便我们二分。
直接斜率优化一下这个东西就好了qwq,毕竟这是 wqs二分 笔记,斜率优化就不展开了。
[代码(有注释](https://paste.ubuntu.com/p/kRGR24JJgh/)
[附不斜率优化的代码](https://paste.ubuntu.com/p/cQrBBygqRW/)
### [P4383 【八省联考2018】林克卡特树](https://www.luogu.com.cn/problem/P4383)
首先,题目可以转化为在一棵树上取 $K+1$ 条互不相交链,最大化这些链之和。
~~希望没有人和笔者一样义为题目意思是选 K 条边并把权置为 0 的吧(~~
然后,根据 wqs二分 基本套路,我们考虑如果没有这个 $K$ 限制我们应该怎么做。
显然,我们可以记录 $f_{i,0/1/2}$ 表示当前在 $x$ 这个点,第 $x$ 这个点是没有用还是作为链中部还是作为链顶。
显然有 dp 转移方程,这里就不列了,具体看代码 ~~,毕竟这是 wqs二分 学习笔记嘛(~~
然后,我们按照 wqs二分 的基本套路,枚举一个差量。
~~然后这题就做完了????~~ 抱歉好像还真做完了。。。
[代码(有注释](https://paste.ubuntu.com/p/rFRyKD93t2/)
## 8. 附录
参考资料:
[浅析一类二分方法](http://www.doc88.com/p-949564862405.html)
[wqs 二分详解](https://blog.csdn.net/a_forever_dream/article/details/105581221)
[题解 P4383 【八省联考2018】林克卡特树](https://www.luogu.com.cn/blog/Marser/solution-p4383)