模板:CDQ分治

UPD:18.06.15修正一些错误,感谢评论区巨佬orz

CDQ分治不是一个顾名思义的东西,CDQ分治是为了纪念神犇陈丹琦而命名的一种算法。

那么CDQ分治能干什么?CDQ分治主要是用来解决一类”操作独立且允许离线“的数据结构题。

(当然要是不能离线的话就树套树吧……)

(PS:其实有”撤销某次操作“也是可以用CDQ分治做的,但是我菜,所以不做讨论。)

——————————————

算法描述:

再次重申CDQ必须满足的条件:

1.修改操作对询问的贡献独立,修改操作之间互不影响效果。

2.题目允许使用离线算法。

然后我们正式开始CDQ分治。

首先我们对询问和修改队列二分,我们就能发现:

1.后半队列对前半队列的操作无影响。

2.后半队列中的询问仅受前半队列操作和它之前的后半队列的操作。

首先对于前半队列,由1可知它没有任何限制,那我们就递归之。

对于后半队列,明显后半队列的修改操作不受前面操作的影响。

那么对于后半队列的询问操作,由2可知该问题完全被转化为了“给定一些操作后进行询问”的静态离线问题,这样极大地降低了我们的编程难度。我们设这个操作的复杂度为O(f(n))。

而我们所搜的深度为O(logn),所以时间复杂度为O(f(n)logn)。

————————————————————————

用法:

有关于CDQ的问题绝大部分都可以转化为三维偏序问题。

所谓偏序问题,通常问比一个点“小”的点有多少个,其中“小”的定义由点本身的性质决定(通常情况下定义当前点的个项性质都大于另一个点,则该点更大)。

而三维偏序问题,就是指这样的一个点的性质一共有三个。

我们的想法是:先排序解决一维(然后将该维度看为查询/修改的时间),然后再CDQ解决二维,最后数据结构解决三维。

这种思维在下面的例题中都有所体现。

至于更高维度的问题,我们可以双重甚至多重CDQ解决(当然树套树套树……?),但是由于编写更加困难,所以采用玄学的bitset解决问题。

比如这道题:

HiHoCoder1513:小Hi的烦恼:http://www.cnblogs.com/luyouqi233/p/8705620.html

————————————————————————

例题:

BZOJ3262:陌上花开 & 洛谷3810:三维偏序http://www.cnblogs.com/luyouqi233/p/8039450.html

BZOJ1176:[Balkan2007]Mokia:http://www.cnblogs.com/luyouqi233/p/8043237.html

BZOJ3295:[Cqoi2011]动态逆序对:http://www.cnblogs.com/luyouqi233/p/8044201.html

BZOJ2716:[Violet 3]天使玩偶:http://www.cnblogs.com/luyouqi233/p/8046555.html

 

posted @ 2017-12-14 19:00  luyouqi233  阅读(698)  评论(2编辑  收藏  举报