Slope Trick小记

应该是非常愚蠢的东西,作用是把常数大而且难写的的 O(nlogn) 优化成常数小而且好写的 O(nlogn)

例题 CF713C。

先考虑令 aii 然后转化成不降序列。

很显然最终答案应该是原序列中出现的数,设 dp[n][x] 表示 bn=x 的最小代价就做完了。

转移方程为 dp[n][x]=miny=1xdp[n1][y]+|xy|

考虑这个过程是在干什么。

好像是在合把两个分段凸函数加起来。

这两个分段函数每一段都是一次函数。

先让我们简化问题,把值域缩小到 O(n) 看看会发生什么。

根据差分,前缀和以及斜率的定义,我们能发现相当于是把每一段 [x,x+1] 的区间的斜率 +1/1

于是我们可以动态维护斜率和这个函数在 0 处的取值,显然如果斜率大于了 1 那么这一段将会被置为 0

因为这是一个凸函数吗,所以斜率一定是单调的。

使用线段树即可做到 O(nlogn)

容易发现若将一次函数改为 k 次函数,那么只需要对其微分即可。

而 Slope Trick 是钻了一个空子:斜率最大只有 n

他维护了每个分割点,表示分割点与分割点直接的斜率差了 1

于是就可以快速计算某处的值是多少。

不过其实 Slope Trick 维护的是最右边那个分割点上面的值,不影响就是。

以及上述维护方法会受到函数定义域的影响,你需要维护每一处点值,而如果要取任意点值就会寄,或者需要使用平衡树维护。

试试看!CF280E

仍然考虑设 dp[n][x] 表示 yn=x

那么转移应该是:

dp[n][x]=miny=xbxadp[n][y]+(aiy)2

容易发现后面那部分是二次函数,如果仍然使用上述思路的话需要证明 dp[n][y] 为分段函数。

考虑归纳。对于第一段一定是一次函数。

关于 [xb,xa] 可以考虑前缀取一个 min 然后再平移。

考虑对于每一段自身平移。能够发现最多只是增加了一段 y=x+c 的部分,剩下部分仍然是二次函数。

考虑其他段平移到这一段的,能够发现是类似的东西。

所以这个操作结束后一定是分段二次函数。再加上一个二次函数还是分段二次函数。

此时使用上述方法维护每一段的斜率即可。因为仍然是凸函数所以可以使用平衡树维护斜率。(有平移操作)

复杂度 O(nlogn),但是我觉得即使是 O(n2) 的也没什么人愿意去写吧。。。。。。

总结:对于一个凸函数,将其求导后维护其每一段也是可以维护其极值点的,这样会比维护原函数简单一些(?),不失为一种维护方法。

如果要一句话总结那就是 f(x)=f(0)+0xdf(x)dx

本文作者:Prean

本文链接:https://www.cnblogs.com/lmpp/p/16711547.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Prean  阅读(98)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
var canShowAdsense=function(){return !!0};
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起