斜率优化入门
什么是斜率优化
对于\(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\)
尝试变形
即只要函数\(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\)为答案
考虑优化
我们观察函数对应点组成的图像。

我们引入新的定义: 凸包,上凸包,下凸包。
对应一个函数点集。我们使用一个橡皮筋(环形)勒住这个点集。其中与橡皮筋(环形)之间接触的,就是构成凸包的点。
上凸包,就是拿一根橡皮筋(不是橡皮环)从上往下勒住点,其中与橡皮筋之间接触的,就是构成上凸包的点。即图中红色线段连接的点。同时上凸包的边具有性质,斜率单调不增。
下凸包。与上凸包类似,不过是从下往上勒住。即图中绿色线段连接的点。同时下凸包的边具有性质,斜率单调不减。
我们以求最小值为例。
显然,最终答案对应的函数的对应点必然处于下凸包内。
枚举\(c\)太满了,我们尝试通过已知的信息求\(c\)。
观察:\(-xa_i+c=b_i\) 注意到对于一个询问,\(x\)是已知的,即这个函数的斜率是已知的。\(c\)的变化等于函数的平移。
显然,在\(c\)从小到大变化上,第一次与点相交时,此时的\(c\)就是答案。
显然,此时函数\(-xa_i+c=b_i\)是下凸包的切线。
我们注意到,由于。下凸包具有性质,斜率单调不减,所以则查询直线的斜率位于切点两侧边斜率之间。
然后由于下凸包具有性质,斜率单调不减,所以我们可以对下凸包的边集二分。二分时比较的是查询直线斜率与凸包边斜率的大小关系,从而定位切点所在的位置。然后切点就找出来了。

浙公网安备 33010602011771号