O(nlnnblnb)
我们发现blnb的最小值点为x=e,也就在2~3之间,而且x=2和x=3的函数值相差不大,也就是说我们划分成2个子问题或者划分成3个子问题的时候,效率是最高的。另一方面,划分成2个子问题的程序比3个的要更好实现,因此我们一般在分治的时候将问题划分为2个子问题。当然在必要时可能会有其他划分方法。
快速傅里叶变换
处理多项式的乘法,分解多项式并应用复数的对称和周期性减少重复计算
快速幂
将求n次幂分为2个n/2次幂的较小问题,而两个小问题是相同的,求出一个就知道另外一个的解
(在树上的分治)
……
数据结构
实际上很多基于树的数据结构都可以认为采用了分治思想,但分治不代表一定是简单的二分。
线段树
数列每次对半切割,区间查找被划分为几个已有的线段树节点的并。
线段树是最基础的数据结构之一,这里较详细地讲一下。譬如给定一个数列1, 2, 3, 4,构造这个数列的线段树。
结果如下:
|---------------|| 1 2 3 4 ||---------------|| 1 2 | 3 4 ||---------------|| 1 | 2 | 3 | 4 ||---------------|
看起来和归并排序的递归过程很像。实际上因为都有分治思想,像是必然的。
那么我们查询区间[2,3]的和,我们会这么走:
[2,3] in [1,4]->[2,2] in [1,2] & [3,3] in [3,4] -> [2,2] in [2,2] & [3,3] in [3,4]
也就是我们将这个区间按照适当的方式(按照已有的划分方法)划分成2个子区间(或者正好不需要划分,继续往下走),得到2个子区间(子问题)的和,再加起来,得到当前区间(大问题)的和。我们很容易知道,这么做的时间复杂度是均摊logn的。
对半划分子问题的优势我们在将归并排序的时候已经讲过了,这里的理由类似。但是像B树等就不是对半划分的。
- 伸展树
数列每次从某个点切割,某个点可以代表一个区间
- 划分树
数列每次按较小的一半和较大的一般切割
- 树状数组
和线段树类似
- ……
一些题目
以下题目分类仅供参考。。
分治 POJ
2083
BZOJ
1095, 2001, 2229, 2287, 2458, 2229, 3614, 3658, 3879, 4025, 4059
CodeForces
321E, 576E
树分治 POJ
1741, 1987, 2114,
BZOJ
1095, 1468, 1758, 2152, 2599, 3365, 3435, 3648, 3672, 3697, 3784, 3924, 4012, 4016, 4372
HDU
4812
CDQ分治 BZOJ
1176, 1492, 1537, 2244, 2683, 2716, 2961, 3262, 3295
总结
我们先介绍了分治法是怎么样的一种思想,并介绍了一些典型(常见)的运用了分治思想的算法和数据结构。我们了解了分治法是如何自顶向下的。实际上现实生活中我们也能见到分治法的运用。我们写一个策划,会将策划的不同环节交给不同的人做,最后总策划再将各个人做好的各个部分的策划修改并整合成最终的总策划。而每个写子策划的人又可能将任务继续下派分发给部门内部多个人员共同完成。可以说,计算机科学中的分治法源于生活。如此重要的思想,我们一定要理解。
评论
查看更多