“倒飞的雁,逆流的河,与反方向的时钟。”
偏序问题
一维偏序
求出有多少个 $j(j\neq i)$ ,满足 $j\leq i$ 。
这个太简单了,就直接 std::sort
一波带走,时间复杂度 $\mathcal O(n\log n)$ 。
二维偏序
求出满足 $i\neq j,a_i\leq a_j,b_i\leq b_j$ 的 $j$ 的个数。
我们可以按照 $a_i$ 为第一关键字来排序,然后来查找 $b_i$ 作为条件因子。
如果这里使用枚举 $j:1\sim i$ 暴力的话,时间复杂度高达 $\mathcal O(n^2)$ ,明显不得行。
所以我们选择一个带 $\log$ 的数据结构优化——树状数组。
将 $b$ 离散化,然后每一次查询前缀和(这里的前缀指的是值域),然后加入即可,时间可以优化到 $\mathcal O(n\log n)$ 。
二维偏序同样可以使用分治来做,考虑双关键字排序,即把 $a,b$ 都加入为排序条件。
这样就会出现三种情况:
- $i,j$ 都在左边;
- $i,j$ 都在右边;
- $j$ 在左边,$i$ 在右边。
对于当前指针 $i$ 的左区间 $1\sim i-1$ 肯定满足 $a_k<a_i$ ,那么就和树状数组的做法一样,我们只需要考虑第二维的贡献。
对于前两种情况,可以考虑递归进行处理。
不过,二维偏序问题使用分治做的话可能有些麻烦,大材小用。树状数组应该是当前最合适的算法。
三维偏序
求点 $j(i\neq j)$ 的个数,满足 $a_i\leq a_j,b_i\leq b_j,c_i\leq c_j$ 。
这个问题似乎不可解,但其实做法很多,也很好扩展,也有 $k$ 维偏序问题,就需要算法不断套下去。
而 $\text{CDQ}$ 分治就是一种较为普遍的求解偏序点对问题的思想。
陈丹琦分治
因此得名,而为 $\text{CDQ}$ 分治,这是一个离线算法。
点对问题
所谓点对问题,就是统计一些特性的点对 $(i,j)$ 的数量,即找到点对 $(i,j)$ 满足函数最值。
类似于归并排序,分五步走:
- 找到当前序列 $[l,r]$ 的中点 $mid$ ;
- 将当前所有点对分为 $3$ 类;
- $l\leq i\leq mid,l\leq j\leq mid$ ;
- $mid+1\leq i\leq r,mid+1\leq j\leq r$ ;
- $l\leq i\leq mid,mid+1\leq j\leq r$ 。
- 将当前序列 $[l,r]$ 拆分为 $(l,mid),(mid+1,r)$ ,然后前两种点对会分别在两个序列中。
- 递归处理前两种点对。
- 设法处理第三种点对。
这样的话,我们把整个序列分为了 $\mathcal O(\log n)$ 层,每一层使用 $\mathcal O(n)$ 的时间来解决,时间复杂度不会高于 $\mathcal O(n\log n)$ ,如果要套上树状数组之类的数据结构的话,时间复杂度就是 $\mathcal O(n\log^2 n)$ 。
经过 $\text{LuckyLeaves}$ 的指导,似乎 $\text{Yxc}$ 的 $\text{CDQ}$ 不太正宗,然后学了一下 $\text{LuckyLeaves}$ 的写法。
- 首先按照第一关键字排序,并对整个区间进行归并;
- 然后在当前区间再把小区间按照第二关键字进行排序(不用考虑还原的问题,因为排完小区间之后才会排大区间);
- 处理第三关键字;
- 递归处理。
$\text{Yxc}$ 写的是人工合并,优点是快;$\text{LuckyLeaves}$ 写的是 $\operatorname{Stl}$ 库,优点是好写。
陌上花开
很明显了,三维偏序的板子。
按照 $a$ 维进行排序,然后归并处理 $b,c$ 两维,特判 $b$ 然后用树状数组处理 $c$ 维。
板子大概就长这样,还没贺懂,往后看看。
AC Code
1 |
|
数点问题
老C的任务
如果是 $\mathcal O(n^2)$ 的话,就直接前缀和一遍过了。
意思就是,我们要把原来 $\mathcal O(n^2)-\mathcal O(1)$ 的时间复杂度转换为 $\mathcal O(n\log n)$ 。
考虑把二维数点问题转换维二维偏序问题。
使用矩阵容斥,使问题转化为求四个整区间。然后转换问题:
求满足 $x_i<x,y_i<y$ 的点的个数的权值和。
AC Code
1 |
|
AC Code another ver.
1 |
|
逆序对
对于不带修的逆序对的话,直接考虑树状数组怼过去,洛谷难度 $\textcolor{orange}{普及-}$ 。
然后思考带修动态逆序对。
对于第 $i$ 个询问,只有区间 $[1,i-1]$ 内的修改会对此次答案进行影响。同样,在归并的时候,左半段的修改同样会对右半段的询问造成影响。