CDQ分治
CDQ分治是一种解决三维、四维偏序的算法。 三维偏序 三维偏序问题形如: 有 $q$ 次询问,每次询问有两种: 修改:会给定 $t$、$x$、$y$、$v$,表示在时刻 $t$,在二维坐标 $(x,y)$ 上加上权值 $v$,修改会永久改变权值 (废话)。 查询:会给定 $t$、$x$、$y$,表示求在时刻 $t$ 时,所有满足 $x’ \leq x$,$y’ \leq y$ 的二维坐标 $(x’,y’)$ 上的权值和。 $q \leq 2 \times 10^5$ $t,x,y \leq 2 \times 10^5$ $v \leq 10^9$ 这种问题都有一个通用的解决方法,就是CDQ分治,接下来我们讲一下算法的原理。 我们先把所有的询问离线下来,然后按时刻(第一维)升序排序,显然排序前和排序后,相同询问答案不变。 接下来我们定义函数 $\text{solve}(l,r)$,代表只考虑 $l \sim r$ 内的修改,然后准确回答 $l \sim r$ 内的询问。 既然是分治,我们就要构建好整个分治思路,像这道题,就这样做: 找到 $mid$ 为区间 $[l,r]$ 的中点 $\left\lfloor \dfrac{l+r}{2} \right\rfloor$。 考虑 $l \sim mid$ 内的修改对 $l \sim mid$ 内的询问的影响:递归调用 $\text{solve}(l,mid)$。 考虑 $mid+1 \sim r$ 内的修改对 $mid+1 \sim r$ 内的询问的影响:递归调用 $\text{solve}(mid+1,r)$。 考虑 $l \sim mid$ 内的修改对 $mid+1 \sim r$ 内的询问的影响: 把 $l \sim mid$ 内的修改,和 $mid+1 \sim r$ 内的询问,统统存入一个数组 $b$。 把 $b$ 中所有元素按 $x$ 坐标(第二维)升序排序。 有人对这一步的正确性有疑问,此处解释一下。 ...