保序回归
概念
给定正整数 \(p\),一张点集为 \(V=\{v_1,v_2,\dots,v_n\}\),边集为 \(E(|E|=m)\) 的 \(\text{DAG}\)。
以及每个点的代价函数 \((y_i,w_i)\),若在 \(G\) 中存在 \(v_i\) 到 \(v_j\) 的有向路径,则有 \(v_i \leq v_j\) 的非严格偏序关系。
求点值序列 \(f\),使得以下代价最小:
这类问题统称为 \(L_p(1\leq p \leq \infty)\) 问题。
链上的贪心算法
\(\text{Approximation}\)
求一个单调不降的序列 \(f\),使得 \(\sum_{i=1}^n w_i|y_i-f_i|^2\) 最小。
\(L_p\) 均值
对于 \(1\leq p < \infty\),称一个集合 \(S\) 的 \(L_p\) 均值为使得代价和 \(\sum_{v_i\in S} w_i|y_i-k|^p\) 最小的 \(k\)。
当 \(p=2\) 时,容易证明 \(S\) 的 \(L_2\) 均值是其带权平均:
引理 \(1\)
\(\forall i \in [1,n)\) 若有 \(y_i>y_{i+1}\),则在最优解中一定有 \(f_i=f_{i+1}\)。
考虑当 \(f_i<f_{i+1}\) 时使用调整法易得更优方案。
算法过程
维护一个单调栈,栈内存四元组 \((l,r,y,w)\),若栈顶的两个四元组的 \(y\) 是递减的,那么就将他们合并。
原本的 \(y\) 变为新的带权平均,\(w\) 直接相加即可。
时间复杂度为 \(O(n)\)。
当然这个做法可以扩展为任意 \(L_p(1\leq p < \infty)\) 问题,瓶颈在于求一个区间的 \(L_p\) 均值。
但如果偏序关系不是链而是更一般的形态,引理 \(1\) 的调整法就会失效,故而这个算法不能在偏序图上拓展。
树上的 \(L_1\) 问题

对于任意的 \(L_1\) 问题,都显然有 \(f\) 的取值集合是 \(y\) 的集合的子集。
故可以设 \(f_{i,j}\) 表示点 \(i\) 取了 \(y\) 集合中的第 \(j\) 小,子树中的最小代价和。
得益于绝对值函数以及绝对值函数的幂是凸的,所以可以用 \(\text{slope trick}\) 进行优化。
基于整体二分的转化
\(S\) 问题
考虑在 \(L_p\) 问题的基础上构造 \(S=\{a,b\}(a<b)\) 问题:在满足所有原限制的情况下,额外要求 \(\forall i,f_i \in [a,b]\)。
引理 \(2\)
若对于 \(S=\{a,b\}(a<b)\),原问题存在一组最优解 \(f\) 满足没有 \(f_i\) 落在区间 \((a,b)\) 中,那么求出 \(S\) 问题的一组解 \(f'\),显然有 \(\forall i,f'_i \in S\)。
若 \(f'_i=a\),则 \(f_i \leq a\),若 \(f'_i=b\),则 \(f_i \geq b\)。
\(L_1\) 上的整体二分
由于 \(L_1\) 的解集是原 \(y\) 集合的子集。
所以将 \(y\) 排序后,对于任意 \(mid\),均有 \(f_i \notin (y_{mid},y_{mid+1})\)。
根据引理 \(2\),我们可以求出 \(S=\{y_{mid},y_{mid+1}\}\) 的解,从而缩减每个 \(f\) 的范围,递归到子问题。
\(L_p(1<p<\infty)\) 上的整体二分
需要将 \(L_1\) 上的二分改为在 \(R\) 上二分。
考虑选取不为某个 \(y_i\) 的 \(a\),那么在 \((a,a+\epsilon)\) 上必然不存在最优解。
解决 \(S=\{a,a+\epsilon\}\) 的问题即可。
网络流求解 \(S\) 问题
由于取值集合大小为 \(2\),令 \(S=\{a,b\}\),原本的偏序限制 \(v_i\leq v_j\) 可以描述为:若 \(f_i=b\),则 \(f_j\) 必须为 \(b\)。
先令所有点均选择 \(a\),然后令 \(G\) 上点 \(v_i\) 的点权为把 \(f_i\) 从 \(a\) 改为 \(b\) 的代价变化量,则原问题即为在 \(G\) 上求解最小权闭合子图。
特别地,当 \(p>1\) 时,代价变化量即为 \(f_i=a\) 时代价的导数,注意判定符号。
树上的 \(L_p(1<p<\infty)\) 问题
有了整体二分,对于树结构的任意 \(L_p(1<p<\infty)\) 问题,都能够做到 \(O(n\log_2 V)\) 的复杂度了。
关键在于树上的 \(S\) 问题可以在 \(O(n)\) 的时间复杂度通过简单的 \(\text{DP}\) 解决。
\(L_{\infty}\) 问题
考虑二分答案,于是对于每个 \(i\),我们能求出 \(f_i\) 的合法范围。
通过拓扑排序就能容易地进行 \(\text{check}\) 了,复杂度为 \(O(m\log_2 V)\)。

浙公网安备 33010602011771号