码迷,mamicode.com
首页 > 其他好文 > 详细

CDQ分治总结

时间:2020-02-04 15:41:33      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:开始   code   noi   log   模板   属性   递归   处理   模板题   

终于学了 CDQ 分治了

简介

CDQ 分治是一个神奇的算法,它可以代替一些毒瘤的数据结构,而且常数极小,但美中不足的是它要求离线。

它一般用来解决序列上的一些点对问题,大概是如下流程:

  1. 将序列分为三类:

    \(l\le i \le mid, 1 \le j \le mid\) 的点对

    \(mid < i \le r,mid < j \le r\) 的点对

    \(l \le i \le mid,mid < j \le r\) 的点对

  2. 显然第一类和第二类我们可以递归处理,所以我们只需要考虑第三类的处理方式。

具体的可以康康 OI-Wiki 上的,写的很好(比我的好多了),虽然码风有些奇特......

例题

二维偏序

可以尝试用 CDQ 分治来写一下树状数组 1 的模板题。

三维偏序

Luogu

给出一些元素,每个元素有三个属性值 a, b, c ,询问对于每个元素 i ,满足 \(a_j \le a_i,b_j \le b_i ,c_j \le c_i\) 的 j 的个数。

首先将序列按照 a 排序,此时的序列已经满足了第一维的有序,然后开始 CDQ 。

我们先递归处理 [l, mid] 和 [mid + 1, r] ,因为我们已经保证了第一维的有序,那么对于 \(i \in [l,mid]\)\(j \in [mid+1,r]\) ,一定有 \(a_i \le a_j\) ,所以我们可以放心的将 [l, mid] 和 [mid + 1, r] 的元素按照 b 排序,然后用两个指针扫描这两段,用树状数组来维护第三维。如果 \(b_i\le b_j\) ,我们就在树状数组中 \(c_i\) 的位置 +1 ,并将指针 i 右移一位,否则我们就在树状数组中统计小于等于 \(c_j\) 的元素个数,即 query(c[j]) ,计入 j 的答案,并将指针 j 右移一位。

复杂度:\(O(n\log^3n)\)

Code

四维偏序

这个需要用到 bitset

复杂度:\(O(\frac{n^2}{32})\)

我也不会

练习题

CDQ分治总结

标签:开始   code   noi   log   模板   属性   递归   处理   模板题   

原文地址:https://www.cnblogs.com/hlw1/p/12259572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!