CDQ 分治学习笔记
学习的目的
在任何一个OIer的职业生涯中,都会碰到一些繁琐的数据结构题,而现在的省选有基本是数据结构大战,可见数据结构的重要性,但是和我说的CDQ有什么关系QAQ???
数据结构写起来,基本上就呵呵了,动不动两三百行的代码,调试时基本万念俱灰。。。(可能是我比较菜QAQ)
这个时候CDQ的用处就很明显的,写起来简单,写起来简单,写起来简单!!!
算法要求与使用
大前提:
CDQ一定是处理离线算法,如果强制在线,还是要么暴力,要么刚数据结构。
使用:
1.区间维护什么的就乱搞了,其实也用不到CDQ,但我们要清楚,区间维护其实就是维护一个二维偏序,具体做法我们稍后再说。
2.CDQ的真正用处在于维护一个三维偏序,一般的做法是套用一个树状数组维护第三维。三维偏序的理解,举个例子给你很多三维坐标如(a,b,c),希望你求坐标满足:
a<x&&b<y&&c<z的点的个数有多少个;
具体实现
很多前辈都说CDQ的写法与归并排序超级像,其实也真的是超级像。
先说一下二维的实现:
如果给你一个区间,有很多点权值,支持单点修改和区间查询。其实树状数组乱秒,考虑CDQ怎么做。
对于每个操作我们必须要维护一个时间序,否则会乱套。那么考虑这么一个事实,每次修改操作一定是对后面发生的询问有影响,而我们已经将操作们按照时间排了序,分治的模型可能就出来了吧QAQ。我们递归枚举左区间和右区间,只是在合并前要多一步,考虑左区间中元素对右区间的影响:
记操作的区间的左端点是x,右端点是y;那么满足
q[i].x<q[j].x
都会对查询有影响,注意我们查询的是两个前缀和:sum[x-1],sum[y];那么我们很清楚查询到x-1时,对这次区间询问的答案应该是减去sum[x-1]的,而到y时,便是加上sum[y]。
好了可以总结一下,CDQ的基本思路就是保证左区间与右区间的修改和查询独立协调后,处理左区间对右区间的影响。
如果左区间的所有元素都不满足于修改条件(见上),那么说明右区间的查询部分是不受限制的,可以直接更新答案。
好了差不多就这样了,如果还是不清楚的话,可以在看几篇博客,知识点不可能看一篇文章就能学会的。
三维偏序
三维偏序其实是对二位偏序的拓展。
我们可以保证默认序时间序是有序的,我们也能保证第二维在维护的时候可以有序,但是第三维我们只能放弃,否则会冲突。这时候我们可以借助一个简单的数据结构,比如说树状数组来维护。
先放一道入门题
比模板题多一点点操作在于只用容斥把查询稍微转化一下就行了
因为有些查询是对答案有利,有些不是,所以定义的时候可以应入一个w变量=1||-1来记录状态。
贴一波同组写的题解
传送门
|
|