算法与数据结构 7.5 - 李超线段树
目录
- 前言
- 由来
- 功能
- 用途
- 原理
- 理论
- 实现
前言
其实李超线段树应该属于斜率优化的一部分,因为这种数据结构常见用法似乎就是斜率优化。但因为不常见(一般是出题人懒得写),所以分到单独的一章。
由来
李超线段树是杭州学军中学的李超(IOI 2012 Au)发明的。
功能
要求在平面直角坐标系下维护两个操作,强制在线:
- 在平面上加入一条线段。记第 \(i\) 条被插入的线段的标号为 \(i\),两端点 \((x_0,y_0)\),\((x_1,y_1)\)。
- 给定一个数 \(k\),询问与直线 \(x = k\) 相交的线段中,交点纵坐标最大的线段的编号。
\(1 \leq n \leq 10^5\),\(1 \leq k, x_0, x_1 \leq 39989\),\(1 \leq y_0, y_1 \leq 10^9\)。、
用途
当使用斜率优化 DP 时,状态转移方程形如:
\[dp[i]=\min/\max\{a[i]\times b[j]+d[j]\}+c[i]
\]
上面的式子,去掉 \(\min/\max\) 后简单变形:
\[dp[i]-c[i]=d[j]-(-a[i]\times b[j])
\]
\[b=y-k\times x
\]
如果式子中的 \(k\) 部分和 \(x\) 部分均不单调,则可以用李超线段树维护凸壳,以较快的时间复杂度找到最优决策点。
原理
理论
暴力的想法是维护 \(x=i\ (1\le i \le 39989)\) 上最高点的位置,但这样做修改是 \(\mathcal{O}(n\times \text{len})\ (\text{len}=39989)\) 的,显然无法通过本题。考虑到这道题需要进行大量的区间修改操作,于是想到线段树维护答案。
考虑让线段树上每个节点维护 \(x=\frac{l+r}{2}\) 处的最高点的 \(y\) 和线段编号。对于懒惰标记(lazy tag)的下传,分类讨论原区间中的最优线段和新加线段的位置关系:
- 新线段在老线段的上方时:直接更新即可。
- 新线段在老线段的下方时:丢弃。
- 新线段和老线段交叉时,不妨设交点在左子区间:
- 对于右子区间,考虑上面两种处理方法;
- 对于左子区间,考虑递归处理。
其余部分按常规线段树处理即可。时间复杂度和普通线段树一样。
实现
原来的代码过于臃肿,正在重写。
本文来自博客园,作者:cwkapn,转载请注明原文链接:https://www.cnblogs.com/cwkapn/p/19005383


浙公网安备 33010602011771号