斜率优化入门

什么是斜率优化

对于\(n\)个一次函数,求将某个 \(x\) 带入这所有一次函数内所获得的最值的方法。形式化的:

  • 给定\(n\)个一次函数\(a_iX+b_i\)

  • 每次询问给定一个\(X\), 求 \(\max \limits_{i=1}^{n}[ a_iX+b_i]\) 或者 \(\min \limits_{i=1}^{n}[ a_iX+b_i]\)

每次查询的复杂度控制在\(O(log_2n)\)或更低。

本文只讲最通用的二分写法,对于特定题目有比 \(log\) 更优的做法,例如单调队列的 \(O(1)\)

另一种方法是李超线段树,复杂度 \(O(log_2v)\),其中 \(v\) 是查询的值域

具体思想/步骤

暴力做法

对应每个一次函数\(y=a_ix+b_i\),我们使用一个点描述这个函数:\((a_i,b_i)\)。我们称该点为函数的对应点。

考虑暴力做法,枚举最值\(c\),然后判断是否有一次函数满足\(c=a_ix+b_i\)

尝试变形

\[c=a_ix+b_i \]

\[c-a_ix=b_i \]

\[-xa_i+c=b_i \]

即只要函数\(y=a_ix+b_i\)满足\(-xa_i+c=b_i\),那么说明将\(x\)带入后,函数的值为\(c\)

我们可以将\(-xa_i+c=b_i\)看作一个一次函数,其中\(-x\)为一次项系数,\(c\)为常数项。\(a_i\)为自变量。\(b_i\)为因变量。

然后只要函数\(y=a_ix+b_i\)的对应点在函数\(-xa_i+c=b_i\)上,则函数\(y=a_ix+b_i\)带入\(x\)的值为\(c\)

那么暴力做法。每次枚举\(c\),然后判断是否有函数的对应点在函数\(-xa_i+c=b_i\)上。然后最 大/小 的合法的\(c\)为答案

考虑优化

我们观察函数对应点组成的图像。

image

我们引入新的定义: 凸包,上凸包,下凸包

对应一个函数点集。我们使用一个橡皮筋(环形)勒住这个点集。其中与橡皮筋(环形)之间接触的,就是构成凸包的点。

上凸包,就是拿一根橡皮筋(不是橡皮环)从上往下勒住点,其中与橡皮筋之间接触的,就是构成上凸包的点。即图中红色线段连接的点。同时上凸包的边具有性质,斜率单调不增

下凸包。与上凸包类似,不过是从下往上勒住。即图中绿色线段连接的点。同时下凸包的边具有性质,斜率单调不减

我们以求最小值为例。

显然,最终答案对应的函数的对应点必然处于下凸包内。

枚举\(c\)太满了,我们尝试通过已知的信息求\(c\)

观察:\(-xa_i+c=b_i\) 注意到对于一个询问,\(x\)是已知的,即这个函数的斜率是已知的。\(c\)的变化等于函数的平移。

显然,在\(c\)从小到大变化上,第一次与点相交时,此时的\(c\)就是答案。

显然,此时函数\(-xa_i+c=b_i\)是下凸包的切线。

我们注意到,由于。下凸包具有性质,斜率单调不减,所以则查询直线的斜率位于切点两侧边斜率之间。

然后由于下凸包具有性质,斜率单调不减,所以我们可以对下凸包的边集二分。二分时比较的是查询直线斜率与凸包边斜率的大小关系,从而定位切点所在的位置。然后切点就找出来了。

posted @ 2026-08-07 22:44  txp2025  阅读(7)  评论(0)    收藏  举报