一个支持动态加入折线段和查询某个区间内所有折线段最高/最低点的数据结构。
支持以下两种操作:
考虑线段树维护坐标轴,每个区间维护一条直线。当一个区间加入一条新直线时,若该区间原来没有直线,则直接用新直线覆盖。
否则,考虑新旧直线的优势长度,这里一条直线的优势长度定义该直线作为区间更优解的长度。
通过比较区间中点的取值可以得到优势长度更大的直线,然后将该区间用优势长度更大的直线的线段覆盖。
另外,优势长度更大的直线一定是整个左区间或整个右区间的更优解,而在另一个区间新旧直线可能各自占用一部分长度的更优解。
于是需要将被取代的直线下放到两个线段自占用一部分长度的更优解的区间来更新答案。
对于查询操作,类似懒标记永久化的线段树,递归过程中不停更新最优解即可。时间复杂度 $O(q\log n)$。
支持以下两种操作:
将线段拆成 $O(\log n)$ 个线段树上的区间,然后套用全局修改算法即可,于是修改操作时间复杂度变为 $O\left(q\log^2 n\right)$。
另外,对于斜率不存在的线段,可以将 $(x,y_0)\to (x,y_1)$ 转化为 $(x,\max(y_0,y_1))$。
给定一棵树,支持以下两种操作:
考虑树剖转化为序列问题,接下来考虑处理更新操作。设 $d(u)$ 表示根节点到 $u$ 的距离,$p=\text{LCA}(s,t)$,分两种情况:
接下来考虑区间查询操作,需要动态维护区间最优解,同时查询过程需要考虑当前区间覆盖线段的影响。
题意
给定 $n$ 个点,第 $i$ 个点有两个权值 $h_i,w_i$。要求选定若干个点,记为 $a_1,a_2\cdots a_k$,其中 $1,n$ 号点必选。
费用为 $\sum_{i=1}^{k-1} (a_{i+1}-a_i)^2+\sum_{i \not \in a}w_i$。要求最小化费用。
题解
设 $s_i=\sum_{j=1}^i w_i$,$f(i)$ 表示 $n=i$ 的情况下的最小费用,于是有状态转移
$$ f(i)=\min\left(f(j)+\sum_{k=j+1}^{i-1}w_i+(h_i-h_j)^2\right)=\min\left(-2h_jh_i+f_j+h_j^2-s_j\right)+h_i+s_{i-1} $$
不难发现问题转化为求 $y=-2h_jx+f_j+h_j^2-s_j(j=1\sim i-1)$ 在 $x=h_i$ 处的最小值,李超线段树模板,时间复杂度 $O(n\log V)$。
题意
给定两条直线,每条直线上依次有 $n$ 个点。然后给定 $m$ 条弦,第 $i$ 条弦的一端位于第一条直线的第 $u_i$ 个点,另一端位于第二条直线的第 $v_i$ 个点。
每次操作可以选择第一条直线的第 $x$ 个点和第二条直线的第 $y$ 个点,然后割断所有 $u\gt x,v\lt x$ 的弦,同时产生 $a_x\times b_y$ 的费用。
要求进行若干次操作割断所有的弦同时最小化费用。$(2\le u_i\le n,1\le v_i\le n-1)$
题解
如果弦 $(u_i,v_i),(u_j,v_j)$ 满足 $u_i\le u_j,v_i\ge v_j$,那割断弦 $i$ 时一定可以割断弦 $j$,于是可以不考虑弦 $j$。
将剩下的弦 $(u_1,v_1),(u_2,v_2)\cdots (u_k,v_k)$ 按 $u_i$ 从大到小排序,一定满足 $v_i\gt v_{i+1}$。
设 $sa(i)=\min_{j\le i}(a_j),sb(i)=\min_{j\ge i}(b_j)$,$f(i)$ 表示割断前 $i$ 条弦的最小费用,于是有状态转移
$$ f(i)=\min_{0\le j\lt i}\left(f_j+sa(u_i-1)\times sb(v_{j+1}+1)\right) $$
然后套用李超线段树求解即可,时间复杂度 $O(n\log v)$。
给定一棵以 $1$ 为根的有根树,树上每个点有两种点权 $a_i,b_i$。
人物可以从所在节点 $u$ 移动到子树中的任意节点 $v$,费用为 $a_u\times b_v$。问人物从每个节点出发到达任意叶子节点的最小费用。
设 $\text{dp}(u)$ 表示人物从点 $u$ 出发移动到任意叶子节点的最小费用,显然有状态转移
$$ \text{dp}(u)=\min\left(\text{dp}(v)+a_u\times b_v\right) $$
每个节点维护子树的李超线段树,然后进行线段树合并即可。
关于李超线段树的合并时间复杂度,普通线段树合并复杂度为 $O(n\log v)$,但是李超线段树合并单个节点时进行了更新操作,需要单独考虑。
首先不难发现每条直线只会作为李超线段中至多一个节点的最优解存在。
而李超线段树的更新操作在每次递归时要么永远删除一条直线,要么将一条直线下放,使这条直线在李超线段树的深度 $+1$。
而一共只有 $O(n)$ 条直线,于是深度和最大为 $O(n\log v)$,根据势能分析法,得更新操作的总时间复杂为 $O(n\log v)$。
于是李超线段树合并的总复杂度为 $O(n\log v)$。