引子
什么是 cdq 分治呢?,其实他是一种思想而不是具体的算法(就和 dp 是一样的),因此 cdq 分治涵盖的范围相当的广泛,由于这样的思路最早是被陈丹琦引入国内的,所以就叫 cdq 分治了
对于 cdq 分治这个思想的拓展十分广泛,但是这些都叫 cdq 的东西其实原理和写法上并不相同不过我们可以大概的将它们分为三类
1.cdq 分治解决和点对有关的问题
2.cdq 分治优化 1D/1D 动态规划的转移
3. 通过 cdq 分治,将一些动态问题转化为静态问题
CDQ 分治解决和点对有关的问题
这类问题一般是给你一个长度为 n 的序列,然后让你统计有一些特性的点对 ( i , j ) (i,j) (i,j) 有多少个,又或者说是找到一对点 ( i , j ) (i,j) (i,j) 使得一些函数的值最大之类的问题
那么 cdq 分治基于这样一个算法流程解决这类问题
1. 找到这个序列的中点 m i d mid mid
2. 将所有点对 ( i , j ) (i,j) (i,j) 划分为 3 类
第一种是 1 ≤ i ≤ m i d , 1 ≤ j ≤ m i d 1 \leq i \leq mid,1 \leq j \leq mid 1≤i≤mid,1≤j≤mid 的点对
第二种是 1 ≤ i ≤ m i d , m i d + 1 ≤ j ≤ n 1 \leq i \leq mid ,mid+1 \leq j \leq n 1≤i≤mid,mid+1≤j≤n 的点对
第三种是 m i d + 1 ≤ i ≤ n , m i d + 1 ≤ j ≤ n mid+1 \leq i \leq n,mid+1 \leq j \leq n mid+1≤i≤n,mid+1≤j≤n 的点对
3. 将 ( 1 , n ) (1,n) (1,n) 这个序列拆成两个序列 ( 1 , m i d ) (1,mid) (1,mid) 和 ( m i d + 1 , n ) (mid+1,n) (mid+1,n)
会发现第一类点对和第三类点对都在这两个序列之中,递归的去解决这两类点对
4. 想方设法处理一下第二类点对的信息
实际应用的时候我们通常都是写一个函数 s o l v e ( l , r ) solve(l,r) solve(l,r) 表示我们正在处理 l ≤ i ≤ r , l ≤ j ≤ r l \leq i \leq r,l \leq j \leq r l≤i≤r,l≤j≤r 的点对
所以刚才的算法流程中的递归部分我们就是通过 s o l v e ( l , m i d ) , s o