决策单调性
四边形不等式
若函数 \(w(i,j)\) 满足对于所有 \(a<b<c<d\) 都有 \(w(a,c)+w(b,d)\le w(a,d)+w(b,c)\),则称 \(w\) 满足四边形不等式。
等价的定义是对于所有 \(a<b\),\(w(a,b)+w(a+1,b+1)\le w(a+1,b)+w(a,b+1)\)。
一维决策单调性
若 \(f_i=\min_j \{g_j+w(j,i)\}\),且 \(w\) 满足四边形不等式,则 \(f\) 满足决策单调性。
BZOJ 2739 最远点
根据旋转卡壳的推论,随着当前要计算的点逆时针转动,距离当前点最远的点也会逆时针转动。所以我们断环为链,在分治过程中对中点 \(i\),找到最小的 \(j>i\) 满足 \(\operatorname{dist}(i,j)\) 最大,然后递归到两边即可。
NOI2009 诗人小G
典中典二分栈。
代码:https://www.luogu.com.cn/paste/2fdafc75。
区间单调性
若函数 \(w(i,j)\) 满足对于所有 \(l'\le l\le r\le r'\),有 \(w(l',r')\ge w(l,r)\),则 \(w\) 满足区间单调性。
二维决策单调性
若 \(f_{l,r}=\min_{l\le i<r}\{f_{l,i}+f_{i+1,r}\}+w(l,r)\) 且 \(w\) 满足四边形不等式与区间单调性,设 \(p_{l,r}\) 为 \(f_{l,r}\) 的最左边的最优转移点,那么:
- \(p_{l,r-1}\le p_{l,r}\le p_{l+1,r}\);
- \(f\) 满足四边形不等式。
根据第一条,我们可以将这样的转移优化到 \(\mathcal{O}(n^2)\),\(n\) 是 \(l,r\) 的范围。
四边形不等式的讨论
直接抄 OI-wiki!
- 若 \(w_1,w_2\) 满足四边形不等式,那么对于所有 \(a,b>0\),\(aw_1+bw_2\) 满足四边形不等式。
- 若存在函数 \(f,g\) 使得 \(w(l,r)=f(r)-g(l)\),那么 \(w\) 满足四边形恒等式。
- 若函数 \(h\) 满足 \(h'(x)\ge 0\) 且 \(h'\) 单调不减,且 \(w\) 满足四边形不等式和区间单调性,则 \(h(w(l,r))\) 满足四边形不等式和区间单调性。
- 若函数 \(h\) 满足 \(h'\) 单调不减,且 \(w\) 满足四边形恒等式和区间单调性,则 \(h(w(l,r))\) 满足四边形不等式。
路径不交性
P5897 [IOI2013]wombats
区间 LCS
给定长度为 \(n\) 的字符串 \(S\) 和长度为 \(m\) 的字符串 \(T\),\(q\) 次询问区间 LCS。
\(1\le n,m\le 3000,1\le q\le 10^5\),时限 8s。
假设 \(n,m\) 同阶。
过于恐怖。我只听懂了 \(\mathcal{O}(n^3+nq)\) 的做法。
暴力就是对于每次询问,设 \(f_{a,b}\) 为第一个串的前 \(a\) 个位置与第二个串的前 \(b\) 个位置的 LCS,然后 \(f_{a,b}=\max\{f_{a,b-1},f_{a-1,b},f_{a-1,b-1}+[S_a=T_b]\}\)。可以发现这个转移类似一个有向的网格图,所以每次询问就是问网格图上两个点之间的最长路。
考虑分治,我们只需要统计经过中线的询问。枚举中线上的每个点,并计算以它为起点到其他每个点的最长路,以及从其他所有点到它的最长路。这个可以直接递推。然后对于每个询问,枚举中线上的一个点,并用中线左右两边的最长路之和更新答案。
设当前分治到的面积是 \(S\),复杂度满足递归式 \(T(S)=2T(\frac{S}{2})+\mathcal{O}(S\sqrt{S})\),解得 \(T(S)=\mathcal{O}(S\sqrt{S})=\mathcal{O}(n^3)\)。加上询问的复杂度 \(\mathcal{O}(qn)\),即可得到总复杂度。
\(\mathcal{O}(n^2\log n+qn)\) 的做法大概是,我们发现当 \(T\) 或 \(S\) 的起始位置 \(+1\) 时,我们可以找到一条轮廓线,只有它的下面的位置的 dp 值会 \(-1\),其他位置不变。然后就不懂了。
网格图分治题
给定 \(3\times n\) 的边带权的网格图,每条边都从左指向右,或者上指向下。求所有可达的点对之间的最短路之和。
还是分治。统计经过每条中线的最短路之和。对于中线左边的点 \((i,j)\) 和中线右边的点 \((i',j')\),答案会加上从上面走、从中间走、从下面走这三种方案的 \(\min\)。枚举其中哪个 \(\min\) 会取到,再枚举中线右边的一个点,这就形成了一个二维数点问题,扫描线即可。