cdq 分治小记
引言
神奇的思路。
我们都知道归并排序,由于已经排好了左半边和右半边,想要求出这一片就很快。而 cdq 就是基于这一过程。
特性
cdq 是离线算法,往往用来解决三维偏序问题。
以 陌上花开 一题为例。假如用暴力做,时间为
过程
首先将第一维按以
由于
注意这一题,还需要把重复的变成一个,否则会出现某些在左边,某些在右边的奇怪情况,导致答案统计不到。
限制
我们从算法的流程中可以知道,在一遍 cdq 分治中,只能有一种顺序,也就是说,只能统计到
代码
常数优化
-
每次做完一个区间后,要清理树状数组,可以考虑时间戳优化。
-
我们发现,对于一个小区间,值域树状数组导致即使
\log 也有 20,这个时候,n\log^2 n 显著的劣于n^2 。对于小区间,直接暴力。 -
这种方式很有效。直接将
sort 变成归并,带来显著的常数优化。和 2 叠加使用时要把暴力的区间也排序了。(需要注意,优化的不是复杂度)
练习
比较基础,都是在各式各样的题面内转化为该模型,将原本的限制都解除。
Mokia
第一维
天使玩偶
这一题要注意的比较多。
- 一次 cdq 只能考虑到一定顺序的,但是考虑转换大小关系,也就是将坐标用四次:
(x,y),(x,inf-y),(inf-x,y),(inf-x,inf-y) ,做 4 遍。(总不会有人写 4 个 cdq 吧) - 卡常。
- 注意不要让值域触及 0。