CDQ分治与整体二分

前言


 

本来想要只讲CDQ分治的,但由于整体二分和CDQ分治有一些相似之处,便顺藤摸瓜一起讲了

在讲解之前,先普及一下在线算法和离线算法的定义

在线算法: 可以以序列化的方式一个一个的处理输入,不必事先知道所有输入数据 

离线算法: 必须事先知道所有的输入数据 (例如选择排序就是一个离线算法,而插入排序则不是)

还有一点,在学习算法前掌握凸壳和斜率优化可能会有神助

 

 

CDQ分治


 

CDQ分治,是一种十分优美的暴力算法。它可以代替很多比较玄学的数据结构,乃广大OIer的福音

但是,不得不感叹一句,网络上关于CDQ分治的讲解实在是太少,而且语言过于抽象,

这导致很多OIer没能接触到其魅力就避而远之。

CDQ分治的关键在于,每个子问题不仅是解决它自身,并且用前一个子问题来求解后一个子问题。常用来将一些动态的问题转化到静态来解决,使问题处理起来更加方便。 
使用CDQ分治需要满足一定的条件:

1.题目允许离线操作

2.修改操作对询问的贡献独立,且修改之间互不影响

3.修改对答案的贡献是确定的,与判定标准无关

4.常数小

揭开这个幌子,先来举例说明这个算法的特点

1.代码简短(比起树套树来说)

2.易想出

3.为离线算法(化动态开点为静态查询),如果需要强制在线的话还是推荐其它算法

和普通的分治一样,分和治在这个算法中都得到了很好的展现

1.我们要解决一系列问题,这些问题一般包含修改和查询操作,可以把这些问题排成一个序列,用一个区间[L,R]表示。

2.分。递归处理左边区间[L,M]和右边区间[M+1,R]的问题。

3.治。合并两个子问题,同时考虑到[L,M]内的修改对[M+1,R]内的查询产生的影响。即,用左边的子问题帮助解决右边的子问题。

 

和很多数据结构(线段树,树状数组。。。)一样,它做了这么多是为了什么?就是为了把符合本次查询的限制的修改对答案产生的效果合并起来 

 

 

 整体二分


 

说完了CDQ分治再来说说整体二分

相对于CDQ分治,整体二分的知名度会更高一些,是很多OIer在解决一些问题时的常用方法

整体二分产生的原因:对于单个查询而言,我们可以采用预处理+二分答案的方法解决,但往往我们要回答的是一系列的查询,对于每个查询而言我们都要重新预处理然后二分,时间复杂度无法承受,但是我们仍然希望通过二分答案的思想来解决,整体二分就是基于这样一种想法——我们将所有操作(包括修改和查询)一起二分,进行分治 

简单地说,整体二分就是对询问和答案同时二分

同样的,整体二分也需要满足一定的条件:

1. 题目允许离线操作 

2. 修改操作对询问的贡献独立,且修改之间互不影响 

3. 修改对答案的贡献是确定的,与判定标准无关 

4. 答案具有二分性

5.贡献满足交换律,结合律,具有可加性

 

 CDQ分治和整体二分的异同


 

同:

1.都是按时间进行分治

2.代码很像(不完全一样,这在异中会讲到)

3.复杂度都是O(f(n)logn)

异:

1.整体二分有二分答案操作

2.适用范围不同(具体看上面的使用条件)

 

 

 

posted @ 2017-11-26 18:01  yodel  阅读(561)  评论(1编辑  收藏  举报