zoukankan      html  css  js  c++  java
  • 模板: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

  • 相关阅读:
    POJ 1673
    POJ 1375
    POJ 1654
    POJ 1039
    POJ 1066
    UVA 10159
    POJ 1410
    POJ 2653
    POJ 2398
    POJ 1556
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8039317.html
Copyright © 2011-2022 走看看