按 @ouuan 大佬所说,CDQ 分治可以当作 ex归并 看待。它的思想和归并排序十分相似:
- 假设要对区间 \([l, r)\) 处理
- 先不管 \([\text{mid}, r)\),计算 \([l, mid)\)
- 同理计算 \([mid, r)\)
- 补回之前忽略的部分,即“归并”
例:三维偏序
给定 \(n\) 个点 \((a,b,c)\),求 \(a_1 \le a_2 \wedge b_1 \le b_2 \wedge c_1 \le c_2\) 的点对 \((a_1, b_1, c_1), (a_2, b_2, c_2)\) 数目。
排序完 \(a\) 这一维后,应用 CDQ 分治,方法如下:
- 假设要对区间 \([l, r)\) 处理(即求 \([l, r)\) 中的点对数)
- 先不管 \([\text{mid}, r)\),计算 \([l, mid)\)
- 同理计算 \([mid, r)\)
- 此时由于是根据 \(a\) 排序的,即使 \([l, mid)\) 和 \([mid, r)\) 已经乱得不像样,我们仍然能保证 \([l, mid)\) 中的点的 \(a\) 是 \(\le\) \([r, mid)\) 的。
- 我们将左右两区间分别根据 \(b\) 排序
- 这样用双指针扫描时,一定能保证 \(a,b\) 都是有序的。
- 用区间数据结构维护 \(c_1 \le c_2\) 的个数即可。(当然也可以 CDQ 套 CDQ)