分治学习笔记
Cutest_Junior · · 个人记录
分治学习笔记
主定理
- 假设有递归关系式
T(n)=aT(\dfrac{n}{b})+f(n) ,其中n 是问题规模,a 是递推子问题数量,\dfrac{n}{b} 为每个子问题的规模,f(n) 为递归以外做的工作:- 如果分治外的操作比
n^{\log_ba} 少,那么总的复杂度为O(n^{\log_ba}) ,更进一步地,可以理解为如果分治外的操作比分治操作增速慢,那么就是分治操作占主要复杂度; - 如果分治外的操作数量级和
n^{\log_ba} 相当,那么总复杂度为O(n^{\log_ba}\log n) ,这是最常见的情况,如果数量级相当,那么总复杂度还要再乘上\log n ; - 如果分治外操作数量级比
n^{\log_ba} 大,那么当n 很大时,总复杂度会趋向于O(f(n)) ,也就是说如果分治外的操作非常慢,那么算法就会被这些操作占主导,分治的作用减弱。
- 如果分治外的操作比
cdq 分治
- 离线算法,常数较小,常用于处理多维偏序的问题。
P3810 三维偏序
曾用动态开点树状数组套动态开点线段树过了。
- 多维偏序问题通常用 cdq 分治解决;
- 先按
a 排序,保证合并过程中前半部分不可能在三个指标上都大于等于后半部分的元素,但是要特判一下相同元素; - 我的方法是排序后去重,并给每一个元素一个权值
s ,表示它在原序列上的出现次数; - 在合并的过程中,对
b 做归并排序,就很容易对后半部分每一个元素判断有多少个前半部分的元素满足a,b 都小于等于它了,至于c 可以用权值树状数组处理; - 具体来说,每加入一个前半部分的元素
i ,就在树状数组的c_i 位置加上s_i ,每加入一个后半部分的元素j 就查询位置小于等于c_j 的区间和; - 在区间内的元素,肯定满足
a_i\le a_j (初始时排序),肯定满足b_i\le bj (归并排序),肯定满足c_i\le c_j (按c 插入树状数组),综上,被计入答案的一定满足条件; - 在区间外而在前半部分中的元素,要么还没插入,则不满足
b_i\le b_j ,要么插入了但在区间外,则不满足c_i<c_j ,综上,没被计入答案的一定不满足条件。