wqs 二分

更应该说是一种思想吧。

我们希望知道恰好选择 k 个物品时的答案,但世界上哪来的那么多恰好呢。令 fx 是恰好选择 k 个物品时的答案,那么点集 (x,fx) 常会形成一个凸包,于是要知道特定 x 的答案,就只需要二分出这个点的斜率,然后用截距加上横坐标乘斜率即可,这个过程就是 wqs 二分,而求最优截距的方法是多样的,下面会说。其中有许多需要注意的细节,比如连着几个值斜率相同(其实没关系,反正最后求出来的答案是一样的)。另外精度也是一个需要考虑的问题。一般用下面这种写法:

while(l<r){
	mid=(l+r>>1)+1;solve(mid);
	if(g[1].num>=n)ans=g[1].data+n*mid,l=mid;else r=mid-1;
	if(g[1].num==n)break;
}

最后出来的 ans 就是我们想要的。其它的倒是没什么了,具体看题。

Akvizna link 忽略轮数的限制,用 fx 代表还剩 x 个人的最大收益。于是有 fx=maxi=0x1(fi+iji),可以拆成斜率优化的形式。推出柿子之后直接 wqs 二分即可,然后似乎要注意精度。

CF739E link 猜测答案在两个维度上都是凸包形式,所以可以二分套二分。检查的过程就变成了对于一个物品,用红球有 pAcA 的贡献,用蓝球有 pBcB 的贡献,两个都用有 pA&BcAcB 的贡献,选择一个希望最大化总贡献,贪心即可,途中记录两种球各用几次。有些卡精度,应当在当前数量等于希望数量时及时推出。

aliens link 经典的题目。把右上的点翻到左下,消除那些对答案不产生影响的点,剩下的点会形成一个锯齿一样的形状,每个点映射到对角线上会有一个区间 [li,ri]。但由于多次选择的区间只会被计算一次,所以方程会稍微复杂一点(一开始以为要多次计算,调了半天才反应过来,毕竟那种思路下根本无法形成凸包)。内部还是用的斜率优化。

忘情 link 和上一道题本质上差不多。柿子题。

林克卡特树 link 转化问题。把树拆成 k 部分,然后要最大化连接起来后的答案,就贪心地选择每个部分中的直径。于是问题就变成了在树上选择 k+1 条不相交的链。因为所以这玩意是上凸的,所以采用 wqs 二分。用 fx,0/1/2 代表这个点当前度数为多少时的最优值,考虑转移。用 gx 代表 x 子树内的答案(也就是到父亲那条边不选),于是有

fx,0=fx,0+gyfx,1=max(fx,1+gy,fx,0+fy,1+e)fx,2=max(fx,2+gx,fx,1+fy,1+e+p)

其中每个值都要记录两维,即答案和选择的链的数量。最后看 groot 选择了几条链并更新左右端点即可。

CF802O link 运用到了 wqs 二分思想的题目。因为所以它是一个凸包,然后就可以用 wqs 二分了。考虑内部如何检查,这里用到了反悔 DP 的思想。考虑一个点作为结束时间时选择谁作为开始时间。如果选择一个没有被选择过的 ay,那么由于当前是一个新的决策,所以贡献是 bx+ayv。如果是顶替掉之前的某个决策,那么贡献的变化值就是 bxby,所以动态维护 ayvby 的最小值并记录第一种决策做了多少次即可。一只 log

posted @   Feynn  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示