模板: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