cdq分治 笔记

算法讲解

这个算法用于解决三维偏序问题。

三维偏序:给定 (n) 个三元组: ((a_i,b_i,c_i)),求同时满足满足 (a_ile a_j,b_ile b_j,c_ile c_j)((i,j)) 的数量。

那这该咋求呢⊙(・◇・)?

先把维度降下来,二维偏序,会不会做?就是求多少个 ((i,j)) 满足 (a_ile a_j,b_ile b_j)

显然,先按照 (a) 排一下序。然后就变成了 (i<j,b_ile b_j) 的问题了。可以用树状数组做。最典型的案例就是逆序对问题,这个都写熟练了哈(*╹▽╹*)

三维偏序的问题,也是先按 (a) 排一下序。然后接下来的问题考虑分治(这样的分治过程被我们称为“cdq分治”)

假设我们要求 ([l,r]) 中的答案。已经求好了 ([l,mid],[mid+1,r]) 中的答案,现在只需要考虑跨区的答案了。

那么我们可以把 ([l,mid])([mid+1,r]) 内部都按照 (b) 排序。因为我们只要考虑跨区的答案,那么我们把两边分别都随便排序,对跨区的时候 (a) 的大小关系没有影响。然后我们在 ([mid+1,r]) 中枚举一个元素 (j),找到在 ([l,mid]) 中有多少个 (i) 满足 (b_ile b_j),然后这个 (i) 显然是递增的。然后我们一边单调的维护这个 (i) ,一边用树状数组维护 (c_ile c_j) 的数量即可。

板子

洛谷3810 陌上花开

代码

原文地址:https://www.cnblogs.com/LightningUZ/p/14141030.html