wqs二分

posted on 2024-06-02 13:34:04 | under | source

简介

wqs(王钦石)二分是一种化恰好无限制的巧妙算法。

考虑一种 01 背包问题:有 \(n\) 个物品,选其中 \(m\) 个,求价值的最值?以最大值为例。

这里的“物品”是广义的,考虑朴素 \(\rm dp\)?受限于状态数过多,复杂度至少 \(O(n^2)\)

wqs 二分运用数形结合分析并简化问题。前提条件:将 \((i,g_i)\) 看成点,在平面直角坐标系上构成上凸包(斜率单调递减)。

其中,\(g_i\) 表示选恰好 \(i\) 个的最大值。求出 \(g_m\) 即可。

我们枚举斜率 \(k\),令一条斜率为 \(k\) 的直线从上往下扫,扫到凸包第一个点 \(p\)。此时若 \(p\le m\),那么必须让斜率 \(\ge k\) 才能扫到 \(m\);反之斜率 \(<k\)。显然可以二分。

现在的问题是,怎么求出 \((p,g_p)\) 呢?

考虑 \(f_i\) 表示直线扫到 \(i\) 时对应截距,即 \(f_i=g_i-ki\)

那么必然 \(f_p=\max f\),所以问题转化为求 \(\max f\)

不妨让所有物品的价值 \(-k\),然后不受限地取就好啦。

共线

注意一个大坑点:凸包上共线的情况。

如果不加以处理,就容易忽略掉正确答案。

具体需要看最后答案输出的是 \(l\) 还是 \(r\),这根据 \(=\) 号取在哪决定。

以输出 \(r\)、上凸包为例,可以每次取得最左端,使得 \(m\) 无论位于共线上哪处时,都可以有 \(r=mid\)

最重要还是因题而异吧。

题目

  • P5633 最小度限制生成树

设计 \(g_i\) 表示 \(s\) 点连了 \(i\) 条边时的 MST 权值。那么 \(g_i\) 构成下凸包。

证明考虑其 MST,不妨设为 \(g_p\),那么选取一条不属于 MST 且与 \(s\) 相连的边,在最小生成树上构成环,类似次小生成树替换得到新的 MST,那么增长值最小的方案就是 \(g_{p+1}\) 了。

显然,改变替换边的顺序不会影响得到的 MST 权值,所以随着 \(p\) 增长,\(g\) 的变化值递增。对于 \(p\) 递减同理。所以是个下凸包。

套 wqs 二分即可,check 部分是容易的。

注意判合法性,注意到下凸包一定是连续的,用斜率为 \(-inf,inf\) 的直线扫出下凸包的左右边界,若 \(k\) 在边界外就是非法的。

  • P1484 种树

考虑最大价值 \(g_p\),将贡献记为 \(0101...\) 的形式。

移动 \(p\),那么必然是将一段连续子串反转,如:\(101\to 010\)。对于所有合法调整,价值必然小于原价值。

考虑 \(g_{p+1},g_{p+2}\),若调整区间不重合,则一定有 \(g_{p}-g_{p+1}\ge g_{p+1}-g_{p+2}\)。否则,重合区间等价于撤销调整,即分别操作 \([l,r]\)\([x,y]\),等于操作 \([l,x-1]\)\([r+1,y]\)\(g_{p+1}-g_{p+2}=val[x,y]\),显然 \(val[x,y]\le val[l,r]\)

斜率递减,构成上凸包。

  • P4694 [PA2013] Raper

显然,新增元素对的顺序无影响,那么必然 \(g_i\) 构成下凸包。

考虑怎么求 \(\max f\),先让 \(a_i-slope\),无限制地选取即可。

注意到 \(1\le a,b\),那么只考虑减去 \(slope\) 后为负数的 \(a\) 即可。

我们只关注选取了那些 \(a,b\),而不关心如何配对。所以等价于选取 \(a_{p_1}\dots a_{p_m}\)\(b_{q_1}\dots b_{q_m}\),且 \(\forall p_i\le q_i\)

从后往前,依次为 \(a\) 配对,贪心地选取最小的 \(b\) 即可,用一个小根堆维护就好了。

注意可以让当前的 \(a\) 替换掉之前的 \(a\),怎么实现?只需将 \(-a\) 加入堆即可。

  • P4383 [八省联考 2018] 林克卡特树

和 lsy 讨论一会儿得出来的。

首先,显然 \(g_i\) 构成上凸包,因为顺序无影响。

那么考虑 \(f_i\) 的实际含义,等价于更改 \(i\) 条边,代价为 \(-i*slope\),然后求直径。

因为删去边会得到森林,最优连边方案显然是将所有树的直径首尾相连。

没必要非得看作森林,关注直径就好了。于是 \(f_i\) 实际上是在原树选 \(i+1\) 条不相交的链,边权和减去 \(i*slope\)

不妨选一条链就 \(-slope\),最后再加上 \(slope\)

然后容易树形 \(\rm dp\),记 \(f_{u,0/1/2}\) 表示对于 \(u\) 子树,\(u\) 未被选、往下延申一条链和随意的最大价值。

为了方便实现,不妨将链只有 \(u\) 一个点的方案也算进 \(f_{u,1}\) 中。转移是容易的。

posted @ 2026-01-14 17:57  Zwi  阅读(0)  评论(0)    收藏  举报