zoukankan      html  css  js  c++  java
  • cdq分治:从归并到cdq套cdq

    感谢 mlystdcall 的透彻讲解

    本文里没有的代码可以去这里查看


    前置芝士

    cdq分治可以用来解决多维偏序问题

    优点:代替复杂数据结构,代码好写(类似归并排序),常数小

    缺点:必须离线

    重要原则:cdq分治归根到底是分治,只用考虑分治后左边对右边的影响,其他的都是递归下去的子问题

    原则不懂可以先记住,边看边理解


    二维偏序

    例:给定N个有序对(a,b),求对于其中的每个的(A,B),满足a<A且b<B的有序对(a,b)有多少个?

    逆序对问题,换了个马甲而已。

    各种数据结构都能水过去

    这里的二维很显然,就是一个a,一个b

    建议用归并排序练习一下

    排序前位置递增,排序后大小递增,在排序的时候统计逆序对。

    归并是cdq的雏形,不能说毫不相干,只能说一模一样

    带修改的类二维偏序

    例:
    有一个n个元素的序列,初始值全部为0,有两种操作:

    操作1:格式为1 x k,把位置x的元素加上k。

    操作2:格式为2 x y,求出区间[x,y]内所有元素的和。

    P3374 【模板】树状数组 1好家伙,马甲都没换

    各种数据结构都能水过去

    用cdq怎么做?

    先找二维分别是啥

    第一维是时间顺序(操作顺序),很容易被忽略

    第二维是操作(询问可以用前缀和的思想拆分为两个位置)的位置

    归并排序前时间递增,排序后位置递增,排序中统计。

    这里详细讲一下。

    归并的时候将lr分为了lmid(简称L)和mid+1~r(简称R)两块。

    一个修改(设为X)怎么才能对一个询问(设为Y)产生影响?X的时间和位置都比Y靠前

    L里的时间都比R早,L里边已经按照位置排好序了(但时间是乱的),R也一样。

    双指针对L和R的位置处理一下就行了,顺便统计。

    三维偏序

    P3810 【模板】三维偏序(陌上花开) 好家伙,马甲都没了

    模板题而已

    一维排序,二维cdq,三维树状数组

    你也可以试试套一下别的

    建议看着代码理解

    代码看这里

    四维偏序/cdq套cdq

    例:给定n个有序四元组(a,b,c,d),求对于每一个四元组(A,B,C,D),有多少个四元组(a,b,c,d)满足a<A && b<B && c<C && d<D。

    其实就是三维偏序加了一维

    套娃开始了

    其实我们可以把这里的(c,d)看做三维偏序里的(c),那么刚才的树状数组就要换成能维护二维信息的数据结构,空间&时间复杂度爆炸

    我们思考一下,cdq优点有哪些?它能把具体的数值变成L和R的区分,省去了比较的过程。我们以L和R区分为基础(此时就省去了一维),再处理剩下的几维。

    按照这个思路,我们cdq的时候其实就是分为了(aL,b,c,d)和(aR,b,c,d),我们顺便记录一下每个元素按照a是属于aL还是属于aR

    我们把这个复制一遍,按照b排序(此时a的乱的,但是根据a带有L或R的标记),我们顺便记录一下每个元素按照b是属于bL还是属于bR

    此时每个元素就是分为了(aL/aR,bL/bR,c,d)

    要是想造成贡献,只能是(aL,bL,c,d)对(aR,bR,c,d)造成的

    然后c这一维双指针,d这一维树状数组


    练习题:
    P3810 【模板】三维偏序(陌上花开)三维偏序
    P5459 [BJOI2016]回转寿司 题解
    P4093 [HEOI2016/TJOI2016]序列
    P4169 [Violet]天使玩偶/SJY摆棋子
    [HZOI 2016]偏序 COGS 2479 四维偏序
    [bzoj2989&4170: 数列]

  • 相关阅读:
    装饰者模式
    代理模式
    享元模式
    模板模式
    命令模式
    建造者模式
    单例模式
    观察者模式
    迭代器模式
    访问者模式
  • 原文地址:https://www.cnblogs.com/wljss/p/14965909.html
Copyright © 2011-2022 走看看