slope trick 学习笔记

对于一个凸函数 fxf_x,若其满足如下性质,则可以使用 slope trick 来刻画:

  • fxf_x 是连续的,即定义域为一个区间;
  • fxf_x 由若干段首尾相连的一次函数拼接而成,且这些一次函数的斜率均为整数
  • 设这些一次函数的斜率的极差为 vv,则 vv 很小(O(v)O(v) 可接受);

具体的,不妨设 fxf_x下凸函数,且其定义域从 00 开始。

注意到每一段一次函数首尾相连,斜率极差很小,且斜率单调不降。所以可以用 f0f_0、第一段一次函数的斜率 k0k_0 和斜率增加点的可重集合 SS 来刻画 ff。具体的,若斜率在某个位置 xx 增加了 Δk\Delta k,则在 SS 中插入 Δk\Delta kxx

例如 f[0,4]=[1,1,3,1,6]f_{[0,4]}=[1,-1,-3,1,6] 这个下凸函数就可以用 f0=1,k0=2,S={2,2,2,2,2,2,3}f_0=1,k_0=-2,S=\{2,2,2,2,2,2,3\} 来描述。

这样刻画的函数性质十分好:

  • 加法:直接将 f0f_0k0k_0 分别相加,并合并两个可重集 SS
  • 求前缀/后缀 min:去掉后面斜率 >0>0 或者前面斜率 <0<0 的部分,对应于删除 SS 中最大或最小的若干个数;
  • 求全局 min:提取斜率为 00 的部分;

并且很容易刻画和绝对值相关的操作。

实际一般使用堆/平衡树来维护 SS

例题:P3642 [APIO2016] 烟火表演