ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

简单 slope-trick

2021-09-26 12:02:29  阅读:312  来源: 互联网

标签:slope le 分段 min max 凸函数 trick 简单 断点


定义与性质

\(\rm slope \ trick\) 通常用于维护 「线性分段凸函数」(如下图) 的相关转移 \(\rm dp\)。

形式化地说,其可以维护的函数 \(f(x)\) 满足:\(f(x)\) 在整数域上为连续凸函数,且考虑 \(f(x)\) 分段的断点 \(x_0, x_1, x_2, \cdots x_k, x_{k + 1} \in \mathbb{N}, x_0 = -\infty, x_{k + 1} = \infty\) 且形如 \(f(x) = k_ix + b_i(x_{i - 1} \le x \le x_i)\)

在此考虑如何维护之前,(不加证明地)给出「线性分段凸函数」的若干简单性质:

  • \(\forall d \in \mathbb{N}\) 若 \(f(x)\) 为「线性分段凸函数」则 \(f(x + d)\) 也为「线性分段凸函数」。

  • 若 \(f(x), g(x)\) 均为「线性分段凸函数」则 \(h(x) = f(x) + g(x)\) 也为「线性分段凸函数」。


基本思路

其基本思路是按照直线斜率正负分开维护左右两个函数。

我们发现:若知道「线性分段凸函数」最低点 \(\min_f\) 与其在值域上 斜率变化量为 \(1\)(若变化量 \(\Delta d > 1\) 则看作这个位置斜率变化了 \(\Delta d\) 次) 的位置(以下简称断点)就可以与原函数构成双射。

因此,对于一个「线性分段凸函数」我们维护一下几个信息:

  • 函数最小值 \(\min_f\)
  • 函数斜率 \(< 0\) 的直线断点构成集合 \(L\),斜率 \(> 0\) 的直线断点构成集合 \(R\)。

为了减少讨论,我们在 \(L, R\) 中事先分别加入 \(-\infty, \infty\) 两个断点。

第一种信息很方便维护,对于第二种信息通常需要使用堆或平衡树来维护。


常见操作

函数最小值

若需要求函数的最小值,显然直接调用维护的 \(\min_f\) 即可。

若需要求函数最小值对应的自变量取值,那么只需调用 \(L\) 集合内位置最大的断点 \(l\) 和 \(R\) 集合位置最小的断点 \(r\),那么 \([l, r]\) 即为所求。

若操作二使用堆维护,单次复杂度 \(\mathcal{O}(1)\);若操作二使用平衡树维护,单次复杂度 \(\mathcal{O}(\log n)\)。

函数平移

由性质一,可知「线性分段凸函数」平移后仍是「线性分段凸函数」,因此维护平移操作是可行的。

显然最小值不变,只需修改 \(L, R\) 两个集合。

考虑维护 \(L, R\) 两个集合坐标平移的变化量即可 \(\mathcal{O}(1)\) 维护。

简单函数的累加

常数函数 \(g(x) = c\)

显然最小值变化量 \(+c\),\(L, R\) 两集合不变,简单 \(\mathcal{O}(1)\) 维护。

绝对值函数 \(g(x) = |x - c|\)

注意到 \(g(x)\) 为「线性分段凸函数」,由性质二 \(f(x) + g(x)\) 也为「线性分段凸函数」。

累加「线性分段凸函数」一般考虑分段依次加入,这样每次加入的都是一条直线。

下面以加入 \(x - c(x \ge c)\) 为例,\(-x + c\) 显然等价。

按照 \(c\) 与 \(max_L, min_R\) 的大小关系分类讨论。

  1. 若 \(c \le max_L\)

此时 \(max_L\) 会从 \(L\) 弹出加入 \(R\),\(L\) 内会加入断点 \(c\)。

最小值 \(\min_f\) 的变化量为:\(max_L - sem_L\)(令 \(\max_L\) 为 \(L\) 一开始的最大值,\(sem_L\) 为 \(L\) 弹出 \(max_L\) 加入 \(c\) 后的最大值)

由于涉及到插入删除操作,使用堆或平衡树复杂度均为 \(\mathcal{O}(\log n)\)。

此时我们继续讨论剩下的两种情况,可以发现三种情况都可以简单地用 一种不需要讨论方式 维护:

令 \(max_L\) 为 \(L\) 在没有变化前的最大值。

将 \(c\) 插入 \(L\),弹出 \(L\) 内最大元素至 \(R\),令此时 \(L\) 内最大值为 \(sem_L\)。

令 \(\min_f \leftarrow \min_f + max_L - sem_L\)。

容易注意到,复杂度为单次 \(\mathcal{O}(1)\)。

函数最值操作

左取 \(\min\):\(g(x) = \min\limits_{y \le x} f(y)\)

只需将 \(R\) 清空即可(注意保留 \(\infty\)),复杂度均摊单次 \(\mathcal{O}(\log n)\)。

右取 \(\min\):\(g(x) = \min\limits_{y \ge x} f(y)\) 类似

区间左取 \(\min\):\(\forall 0 \le a \le b, g(x) = \min\limits_{y \in [x - b, x - a]} f(y)\)

最小值 \(\min_f\) 不变。

\(L\) 集合向右整体平移 \(a\) 个单位,\(R\) 集合向右整体平移 \(b\) 个单位。

类似函数整体平移的方式维护,复杂度单次 \(\mathcal{O}(1)\)。

区间右取 \(\min\):\(\forall 0 \le a \le b, g(x) = \min\limits_{y \in [x + a, x + b]} f(y)\) 类似

区间左取 \(\max\):\(\forall 0 \le a \le b, g(x) = \max\limits_{y \in [x - b, x - a]} f(y)\)

分两类情况:

  • \(b - a \le \min_R - \max_L\)

最小值 \(\min_f\) 不变。

\(L\) 集合向右整体平移 \(b\) 个单位,\(R\) 集合向右整体平移 \(a\) 个单位。

类似函数整体平移的方式维护,复杂度单次 \(\mathcal{O}(1)\)。

  • \(b - a > \min_R - \max_L\)

也即对两个函数 \(L(x - b), R(x - a)\) 取较大者。

考虑维护 \(L, R\) 内第一个断点和第二个断点构成的线段 \(a, b\)。

每次弹掉 \(L, R\) 内第一个断点对应函数值较小的那个点直到 \(a, b\) 相交,令该点为 \(P\)。

则 \(\min_f\) 的值即为 \(P\) 在 \(a\) 上的取值,然后把 \(L, R\) 分别插入斜率变化量个 \(P_x\) 即可。

均摊复杂度单次 \(\mathcal{O}(\log n)\),但因为 \(P_x\) 不一定为整数所有这类问题比较少见。

区间右取 \(\max\):\(\forall 0 \le a \le b, g(x) = \max\limits_{y \in [x - b, x - a]} f(y)\) 类似

图片来源与参考

标签:slope,le,分段,min,max,凸函数,trick,简单,断点
来源: https://www.cnblogs.com/Go7338395/p/15337449.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有