[国家集训队] Tree I

借助这道题目把wqs二分讲明白

考虑如下一个问题:

现在一共有若干个物品,物品被分成两组,现在从中选出若干个物品,但是题目会给出某种限制(也就是在这种限制条件下,物品的选择不是随意的,所有选择集合中,只有一些集合符合题目给出的限制,这样的集合才可以被选择),这种限制只跟物品本身有关而跟其权值无关(i.e. 对一个相同的物品选择集合,其中的物品权值无论如何变化,这个集合的合法性都不改变),而且必须从第一类物品中选出\(p\)个,问如何选择最优

我们设\(g(x)\)表示从第一类物品选出\(x\)个且满足题目限制的最优答案,如果说\(g(x)\)是一个凹凸函数,那么就可以利用wqs二分

比如\(g\)长成下面这个样子

那么如果题目给出的\(p=9\),那么答案就是\(g(9)=5\)

显然我们是不能求出\(g(x)\)的(否则可以直接输出了),我们要想办法把\(g\)搞出来

假设现在有一条直线,斜率为\(k\),令其通过函数上的每一个点(注意函数是离散的),则有

通过\((x_0,g(x_0))\)的直线方程就是\(y-g(x_0)=k(x-x_0)\)

我们给第一类物品的权值都减去\(k\),然后不管\(p\)了,在题目的限制条件下跑出来一个值\(res\),那么\(res\)是什么?

\(res\)其实就是上面画的所有直线的截距的最大值

为什么?我们将直线写成\(y-kx=g(x_0)-kx_0\),注意现在\(k\)是已知量。在最初的情况下,假设我们对每个\(x_0\)都跑出来了一个最优解\(g(x_0)\),而在减\(k\)的情况下,每个\(x_0\)的最优解就是\(g(x_0)-kx_0\)(因为权值的变化不会影响限制)。由于现在我们不管\(p\)了,只在题目的限制条件下跑出来了一个最优解,那么就是我们遍历了所有\(x_0\)取最优解的最优解,也就是\(max(g(x_0)-kx_0)\);在方程\(y-kx=g(x_0)-kx_0\)中令\(x=0\),则\(y\)的值就是截距,且值为\(g(x_0)-kx_0\),所有截距的最大值就是\(max(g(x_0)-kx_0)\),刚好就是我们跑出来的这个值;而截距最大显然就是经过切点的直线,也就是说我们获得了切线

然后我们去检查此时第一类物品选出的个数,很显然可以根据这个个数与\(p\)的相对大小进行二分的调整,最终当第一类物品刚好选出\(p\)个的时候,我们将跑出来的\(res\)加上\(kx_0\)即可获得题目要求的答案

然后这一道题目的\(g\)可以证明是有凹凸性的(然而我却没有看到一个严格的证明),但是现在还有一个问题,当我们二分的值为\(mid\)的时候跑出来的白边有比\(need\)多,二分的值为\(mid+1\)的时候跑出来的白边比\(need\)小(或者当我们二分的值为\(mid\)的时候跑出来的白边有比\(need\)少,二分的值为\(mid-1\)的时候跑出来的白边比\(need\)多,下面以前者为例进行分析),这怎么办?

此时当然可以二分实数,然而很容易TLE,所以我们来考察函数

显然\(g(x)\)的值都是整数,而且题目又保证了有解,也就是说\(g(need)\)是存在的,我们考察\(g(need-1)\)\(g(need)\)

image

显然斜率为\(tan\theta\),而\(tan\theta=\frac{g(x)-g(x-1)}{1}=g(x)-g(x-1)\)为整数,也就是说图中任意两个点之间的连线的斜率为整数

然后我们再来考察发生上述情况会怎么样,只有可能像这样:

其中绿色的是我们二分的斜率,然后我们的算法跑出来的是第三个红点(从左往右),我们需要第二个红点,当斜率减一的时候,就直接把三个红点都舍弃了

所以此时就有一个很简单的解决方法了:在Kruscal的排序中,点权相同的将白边摆在前面,然后再更新即可。由于我们是在选出白边不低于\(need\)条时更新答案,这样就可以保证在斜率为\(mid\)时,跑出来的一定是第三个点,根据上文提到的“\(res\)加上\(kx\)”,我们就可以直接更新答案了

还有这两篇博客一博客二还没看(由于wqs二分与费用流的关系很大,所以学了网络流之后再看)

update 2024.7.14

可以好好看看代码,注意不要每次二分都重新排序,而是最开始就将两类边分开,然后利用归并排序即可

posted @ 2024-05-22 18:08  最爱丁珰  阅读(10)  评论(0编辑  收藏  举报