【学习笔记】分治

分治相关的东西我基本都不会。

CDQ 分治

最经典的分治,一般用于去掉一层偏序。

对于一个区间 \([l, r]\) 的答案,我们可以找一个中点 \(mid\),递归计算出 \([l, mid]\) 的答案,然后考虑 \([l, mid]\)\((mid, r]\) 的答案造成的贡献,累加上去之后再递归的求 \((mid, r]\) 的答案。

这其中如果每个区间的贡献的计算需要 \(O(f(len))\),那么总时间复杂度就是 \(O(f(n) \log n)\)

由于每次从重点分,这样递归的层数就是 \(\log\) 的,每一层的长度和是 \(O(n)\),所以总复杂度就是多一个 \(\log\)

最经典的例子就是三维偏序。我们先按第一维排序,然后考虑左区间与右区间之间的二维偏序即可。

动态变静态

对于动态问题,我们可以离线下来静态去做。具体就是把第一维看作时间,那么操作对询问的贡献可以看作一个偏序关系,就可以用 CDQ 解决。

决策单调性分治

形如 \(f_i=\max_{j<i}\{f_j + w(j, i)\}\) 的 DP。

如果设能够使 \(f_i = f_j + w(j, i)\),即 \(f_i\) 的决策点为 \(u(i)\),满足 \(i < j, u_i \le u_j\),则称它有决策单调性。

这意味着,我们可以用分治来解决这件事。对于 \(mid\) 来说,如果 \(mid\) 的决策点为 \(u(mid)\),那么 \(i \in [l, mid)\) 来说,就有 \(u(i) \le u(mid)\),也就是如果原决策点的区间为 \([L, R]\),那么左区间 \([l, mid)\) 的决策点就在 \([L, u(mid)]\) 中,\((mid, r]\) 的决策点就在 \([u(mid), R]\) 中。我们可以根据这个进行分治。

四边形不等式

如果上述函数满足 \(i_1 < j_1 < i_2 < j_2, w(i_1, j_1) + w(i_2, j_2) \ge w(i_1, j_2) + w(i_2, j_1)\)(即:交叉优于包含),那么该 DP 具有决策单调性。

P6932 [ICPC2017 WF]Money for Nothing

决策单点调性板题。

首先发现如果有 \(a_i < a_j, b_i < b_j\),那么 \(j\) 一定是不优的。所以我们可以将这些没用的删掉,剩下的就满足 \(a_i < a_j, b_i > b_j\) 了。

把每对数看作平面上的点,那么所求的实际就是一个最大的矩形。简单画一下发现这个面积满足四边形不等式,那么直接决策单调性分治解决即可。

P5574 [CmdOI2019]任务分配问题

首先简单计算发现贡献满足四边形不等式。

但是发现决策点不好计算,单次计算答案都需要 \(O(n \log n)\)

用莫队的方法做就行了。

最值分治

一般在贡献有区间 \(\max / \min\) 的时候有用。

如果我们的贡献里有区间的 \(\max\),那么我们可以每次取出区间内的最大值,这样跨过这个点的 \(\max\) 就都是这个点,这样左区间对右区间的贡献就是固定的了。

但是这样的问题就是层数不是 \(\log n\) 的了,如果直接做还是可能被卡成 \(O(n^2)\)。假设我们分割的左区间长度为 \(llen\),右区间长度为 \(rlen\),那么如果我们能够做到某一个区间内复杂度为 \(O(\min(llen, rlen))\)(也就是复杂度为较小的一边的长度),就同样可以 \(n \log n\) 做出这个问题。(因为这个过程其实就是启发式合并的逆过程,有人叫它启发式分裂)

CF1442D Sum

posted @ 2023-01-07 17:20  APJifengc  阅读(73)  评论(0编辑  收藏  举报