CDQ分治与整体二分

本文介绍了CDQ分治和整体二分两种离线算法,这两种算法基于分治思想,常用于解决树套树问题。CDQ分治的核心在于归并排序中的逆序对计算,通过分治处理三维偏序问题,整体二分则适用于动态区间第k小问题。文章通过实例详细讲解了这两种算法的实现与应用。
摘要由CSDN通过智能技术生成

前言

CDQ分治和整体二分都是离线算法,并且都是基于分治的思想。大部分非强制在线的树套树题都可以使用整体二分或CDQ分治解决,当然也有一些是不行的,比如动态求区间种类数或者动态求区间 m e x mex mex

CDQ 分治

分治

首先要了解什么是分治,分治的全称为分而治之,英文名为 d i v i d e   a n d   c o n q u e r divide\ and\ conquer divide and conquer,和分治相关的算法有很多,譬如线段树,点分治,归并排序等。下面以归并排序为例。
在归并排序中,我们的算法分为以下流程:

  1. [ l , m i d ] [l,mid] [l,mid] 排序
  2. [ m i d + 1 , r ] [mid+1,r] [mid+1,r] 排序
  3. [ l , m i d ] [l,mid] [l,mid] 的序列和 [ m i d + 1 , r ] [mid+1,r] [mid+1,r] 的序列合并,这一步的复杂度是 O ( r − l + 1 ) O(r-l+1) O(rl+1)

这样子的复杂度是 T ( n ) = 2 T ( n 2 ) + O ( n ) = O ( n l o g n ) T(n)=2T(\frac{n}{2})+O(n)=O(nlogn) T(n)=2T(2n)+O(n)=O(nlogn) 的。
而在归并排序的过程中,我们可以顺便把逆序对给求出来,这个求逆序对的思想就是 c d q cdq cdq 分治的核心思想。
具体过程就是,先求出 [ l , m i d ] [l,mid] [l,mid] 的逆序对,再求出 [ m i d + 1 , r ] [mid+1,r] [mid+1,r] 的逆序对,再求出 x ∈ [ l , m i d ] , y ∈ [ m i d + 1 , r ] x\in[l,mid],y\in[mid+1,r] x[l,mid],y[mid+1,r] 的逆序对 ( x , y ) (x,y) (x,y) 的数量。由于原序列已经满足了 x < y x<y x<y,我们只需要求 a x > a y a_x>a_y ax>ay 的数量。因此我们可以想到先让 a x , a y a_x,a_y ax,ay 有序,然后根据单调性来求对数,而这个让 x , y x,y x,y 有序,即是归并排序的一个过程。

三维偏序

比如我们要求 a j ≤ a i , b j ≤ b i , c j ≤ c i a_j\le a_i,b_j\le b_i,c_j\le c_i ajai,bjbi,cjci ( i , j ) (i,j) (i,j) 对数。
容易想到,我们先按 a a a 排序,然后在这个序列的基础上求解 b , c b,c b,c这个容易用树套树解决
那么我们仍然考虑分治,先求 [ l , m i d ] [l,mid] [l,mid] 的,再求 [ m i d + 1 , r ] [mid+1,r] [mid+1,r] 的,现在只需要考虑 x ∈ [ l , m i d ] , y ∈ [ m i d + 1 , r ] x\in[l,mid],y\in[mid+1,r] x[l,mid],y[mid+1,r] 的点对 ( x , y ) (x,y) (x,y) 了。注意到,由于原序列已经按 a a a 排序,我们只需要找 b x ≤ b y , c x ≤ c y b_x\le b_y,c_x\le c_y bxby,cxcy 的点对 ( x , y ) (x,y) (x,y) 的数量。如果我们可以让 b x , b y b_x,b_y bx,by 是有序的,也就是 [ l , m i d ] [l,mid] [l,mid] [ m i d + 1 , r ] [mid+1,r] [mid+1,r] 中是按 b x , b y b_x,b_y bx,by 升序的。因此我们只需要使用归并排序,在这个过程中用一个树状数组统计答案就好了。
需要注意的是,我们需要先把 a i = a j , b i = b j , c i = c j a_i=a_j,b_i=b_j,c_i=c_j ai=aj,bi=bj,ci=cj 的情况合并为一种。
复杂度是 T ( n ) = 2 T ( n 2 ) + O ( n l o g n ) = O ( n l o g 2 n ) T(n)=2T(\frac{n}{2})+O(nlogn)=O(nlog^2n) T(n)=2T(2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值