CDQ分治与整体二分
Posted yodel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.适用范围不同(具体看上面的使用条件)
以上是关于CDQ分治与整体二分的主要内容,如果未能解决你的问题,请参考以下文章
cdq分治整体二分bzoj 3110: [Zjoi2013] HYSBZ - 3110 K大数查询