李超树学习笔记

李超树是线段树的一种实际应用,能够动态维护二维直角坐标系中的若干条线段 $y = k x + b, \ x \in S$ 在 $x$ 的某个取值 $x_0$ 处的最值。

基本思想

考虑暴力解决这个问题,每次遍历 $n$ 条线段找到最大值,单次复杂度是 $O(n)$ 的。而李超线段树的核心思想就是去掉不可能的结果,缩小遍历的范围,从而达到更低的复杂度。

对于在权值线段树上的修改操作,神仙 tommy 的博客讲的很🐮,这里引用一下:

维护区间内可能成为最优解的线段,且保证时间复杂度就成了这个算法的核心问题。对于这一问题,我们可以使用斜率和线段在当前区间中点上的取值,进行分类讨论。这里就以求最大值为例进行分析。

  1. 若当前区间内没有任何线段,则直接将新线段放入当前区间。
  2. 若当前区间 $[l, r]$ 内有旧线段,且新线段的斜率大于旧线段的斜率,设当前区间中点为 $m$:

    • 若旧线段在 $m$ 上的取值大于新线段在 $m$ 上的取值,则新线段在 $[l, m]$ 上的取值一定不比旧线段更优,但新线段在 $[m + 1, r]$ 上的取值可能更优,将新线段下放至 $[m + 1, r]$ 区间并递归更新答案。

    • 若旧线段在 $m$ 上的取值小于新线段在 $m$ 上的取值,则旧线段在 $[m + 1, r]$ 上的取值一定不比新线段更优,但旧线段在 $[l, m]$ 上的取值可能更优,用新线段替换该当前节点的旧线段,将旧线段下放至 $[l, m]$ 区间并递归更新答案。

  3. 若当前区间 $[l, r]$ 内有旧线段,且新线段的斜率小于旧线段的斜率,设当前区间中点为 $m$:

    • 若旧线段在 $m$ 上的取值小于新线段在 $m$ 上的取值,则旧线段在 $[l, m]$ 上的取值一定不比新线段更优,但旧线段在 $[m + 1, r]$ 上的取值可能更优,用新线段替换当前节点的旧线段,将旧线段下放至 $[m + 1, r]$ 区间并递归更新答案。

    • 若旧线段在 $m$ 上的取值大于新线段在 $m$ 上的取值,则新线段在 $[m + 1, r]$ 上的取值一定不比旧线段更优,但新线段在 $[l, m]$ 上的取值可能更优,将新线段下放至 $[l, m]$ 区间并递归更新答案。

  4. 若当前区间 $[l, r]$ 内有旧线段,且新旧线段斜率相同,比较截距 $b$,截距大的线段在 $[l, r]$ 上的取值一定优于截距小的线段,直接用截距大的替换截距小的。

可以通过标记永久化实现。可以证明,查询和全局修改的复杂度是 $O( \log n)$,区间修改的复杂度是 $O( \log^2 n)$,不过常数好像很小?

其实这篇博文是个板子存放处

模板

[JSOI2008]Blue Mary开公司 - 全局修改 & 全局单点查询

code here

由于我的线段树是预处理区间左右端点的,全局操作变得异常好写(

[HEOI2013]Segment - 区间修改 & 区间查询

code here

[SDOI2016]游戏 - 剖上树

code here

[CEOI2017]Building Bridges - 优化 dp

solution here

code here

文章作者: fa_555
文章链接: https://blog.fa555.tech/2020/Li-Chao-Tree/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 fa_555's Blog