首页 > 其他分享 >纯粹分治

纯粹分治

时间:2023-01-15 10:25:37浏览次数:42  
标签:... log 复杂度 分治 纯粹 ri leqslant

概述

  • 纯粹分治是分治思想最纯粹,最朴实,最本质?的应用。

  • 我不太会描述...一个典型是平面分治计数。还是看例题吧...

例题

Public NOIP Round #3 数圈圈

  • 题意:求一个二维矩阵中的圈的数量。所谓圈,就是字母全部相同的一个矩形壳。

  • 数据范围:\(n,m\leqslant 2\times 10^3,6s\)。

  • 首先这道题暴力乱搞好像能拿不少分...就是暴力枚举左上角,使用一定的剪枝来枚举长宽。

  • 不过我们来谈谈正解吧:二维分治。

  • 每次取矩阵较长的一边的中点将其分割开,计算跨分割线的圈数。为什么要取较长的在复杂度分析部分会用到。

  • 考虑怎么计算 匚 这种形状的数量,因为两边是对称的,左右分割和上下分割是同构的,所以我们只讨论 匚 的求解:

    • 暴力枚举其在分割线上的上界和下界,不妨记其横坐标分别为 \(u,v(u<v)\),纵坐标为 \(mid\),这里我们采用 OI 坐标系。

    • 整一点悬线法的手法,记 \(U_{x,y},D_{x,y},L_{x,y},R_{x,y}\) 分别为 \((x,y)\) 向上/下/左/右的极大同字母延伸位置(下面使用时可能省略部分下标),于是求的其实是 \(\sum\limits_{i=\max(L_u.y,L_v.y)}^{mid} [D_{u,i}\geqslant v]\)。

    • 先考虑 \(L_u.y>L_v.y\) 的情况,此时上式相当于 \(\sum\limits_{i=L_u.y}^{mid} [D_{u,i}\geqslant v]\),显然我们可以通过在 \(u\) 上开 \(D_{u,i}\) 的桶+预处理后缀和来 \(O(1)\) 地算出上式的值。

    • 如果不然,则 \(D\) 变成 \(U\),其实是对称的。

    • 当然后缀和也可以通过树状数组实现,如果把 \((u,i)\) 的影响视为给 \(D_{u,i}\) 上 \(+1\) 的话。因为 \(6s\) 而且 \(n\) 只有 \(2\times 10^3\),纸面也才 \(4.8\times 10^8\) 的双 \(\log\) 做法也是随便过的。

    • 当然,关键是要证明分治本身是 \(O(n^2\log)\) 的。

      • 记当前处理的子矩阵短边边长为 \(x\),长边边长为 \(y\),则预处理部分的复杂度是 \(O(xy)\);

      • 我们的分割线一定是短边,于是枚举是 \(O(x^2<xy)\) 的。

      • 两者合计 \(O(xy)\),那么可以看出,每层是 \(O(nm)\) 的。于是分治的复杂度是 \(O(n^2\log)\)。

  • 那么其实一共是八种对称的情况,分讨一下就可以了。实现细节较多,但对称性使得相对可调一些。

CF364E Empty Rectangles

  • 题意:求一个二维 \(01\) 矩阵中的和为 \(K\) 的矩形数量。

  • 数据范围:\(n,m\leqslant 2.5\times 10^3,K\leqslant 6,12s\)。

  • 考虑使用二维分治,仍然每次取长边中点划分。考虑怎么求这个东西,我们还是希望枚举其在分割线上的上下端点,求出右边和为 \(x\) 的方案数。

  • 注意到这道题好像没有上一道那种优美的“无关性”,\(u,v\) 之间的那些行的影响不容易快速计算...故转而考虑递推,即在已经知道 \(u,v\) 的方案数的情况下,递推出 \(u,v+1\) 的方案数。

  • 考虑手模一个样例看看:

\[\begin{matrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 1 & 1 \end{matrix} \]

  • 其中最左边一列即为第 \(mid\) 列。

  • 首先考虑 \(u=v=1\) 的情况,此时我们直接暴力扫到左边就行。

  • 然后考虑加入第二行的影响。思考实际意义,发现原本向左延伸 \(1,2,3\) 的矩阵和为 \(1,1,2\),然后现在变成了 \(1,2,3\)。

  • 加入第三行,变成 \(2,4,6\)。

  • 唔...发现如果把同一列的 \(1\) 垒起来成为一个数,那么它就是和数组的差分数组。看起来有点废话,但这告诉我们,新的 \(1\) 的效果是后缀加...显然可以通过维护差分数组的方式来用树状数组快速求 \(x\) 延伸的矩阵和。

  • 但,怎么求矩阵和为 \(x\) 的延伸有多少种呢?

  • 仍然考虑这个后缀加。它其实是把从它向右的所有延伸带来的矩阵和都 \(+1\);\(1\to 2,2\to 3,etc.\)。设加入其之前,其对应位置的和为 \(x\),则 \(\forall x'>x\),其改变容易计算;关键是和恰为 \(x\) 的那些延伸有多少变了,有多少没变。

  • 考虑暴力!既然 \(K\leqslant 6\),那么这个“分段函数”的拐点至多有 \(6\) 个。称比左边大的点为拐点,强行记录每个拐点的位置,设插入前为 \(x\),则相当于在插入处创建一个 \(x+1\) 的拐点,插入处以右的每个拐点对应的值 \(+1\),\(>6\) 的拐点不必维护,没有价值。

  • 那我们来分析一下这个复杂度。发现...发现崩了啊!从 \(u=v=up\) 扫到 \(u=up,v=dw\) 就 \(O(xy)\) 了,这...这...

  • 考虑进一步挖掘性质,优化计算。注意到 \(K\leqslant 6\),扩展行的 \(0\) 对计数无影响,于是事实上我们只需要维护每一行的至多前 \(7\) 个 \(1\) 的位置。预处理扫一遍的复杂度 \(O(xy)\),从 \(u,v\) 递推到 \(u,v+1\) 的复杂度是 \(O(6\log)\) 左右,相当于 \(O(x^2\log)\)。

  • 故总复杂度至少可以分析到 \(O(n^2\log^2)\),纸面 \(9\times 10^8\),应该足够过了。

  • 上面是我想出来的办法...但显然实现太烦人了。看了题解之后,发现有更妙的办法:

  • 我们刚才的所谓拐点,也即 \(sum=x\) 的起始位。我们现在考虑转而维护 \(sum=x\) 的结束位,即定义 \(ri_x\) 表示左边界为 \(u\to v\),内部和 \(\leqslant x\) 的矩形的右边界最大到哪里。

  • 那么显然差分容易求得特定和的方案数,考虑怎么维护这个 \(ri\),仍然使用递推,每次递推之后仍然按顺序考虑前 \(6\) 个 \(1\):

    • 对于 \(ri_x<pos\) 的:没有影响。

    • \(ri_x\geqslant pos\) 的第一个:\(ri_x=pos-1\)。注意有时候可能 \(ri_x=ri_{x-1}\),这也许需要一点特判。

    • 其他:\(ri_x=ri_{x-1}\)。注意转移顺序。

  • 啊...是的。要好得多,还没有树状数组的 \(\log\)。这样一来就能把 \(K\) 的常数考虑进来了,不怕被卡常。

UVA1608 不无聊的序列 Non-boring sequences

  • 题意:判断 \(S\) 是否 boring。所谓 boring,就是存在 \(S\) 的子串 \(s\) 满足 \(s\) 中不存在只出现一次的元素。

  • 数据范围:\(n\leqslant 2\times 10^5\)。

  • 注意到若 \(S\) 不 boring,则 \(s_{1\sim n}\) 中必有只出现一次的元素。找到它然后左右区间变成子问题,递归求解即可。

  • 注意到若我们每次都从左向右找,则可能构造一个数列 \(112233445678\) 使得我们的复杂度为 \(O(n^2)\)。改为从两边向中间扫,\(T(n)=T(n-x)+T(x)+O(x)(x\leqslant n-x)\),这个东西的上界是 \(O(n\log n)\)。

标签:...,log,复杂度,分治,纯粹,ri,leqslant
From: https://www.cnblogs.com/weixin2024/p/17053131.html

相关文章

  • CDQ 分治
    例题P3157[CQOI2011]动态逆序对题意略。一开始想了半天,老半天的前后缀主席树做法(分别对前后缀开桶,模仿树状数组求逆序对,算贡献),最后还是发现似乎没办法统计算重的......
  • 分治优化
    概述分治优化常常在DP的转移有某种单向单调性时使用,通过类似整体二分的结构,确保每个决策点只在一条链上出现,从而加速转移。一般这种分治优化也有对应的二分栈形式,区别......
  • 树分治
    概述树分治通过树的唯一连通性质,递归地求解树上路径(主要是路径长度)相关的问题。树分治主要包括点分治和边分治,但到目前为止我都不知道边分治有什么用。点分治......
  • LeetCode刷题(46)~颠倒二进制位【循环/分治】
    题目描述颠倒给定的32位无符号整数的二进制位。示例1:输入:00000010100101000001111010011100输出:00111001011110000010100101000000解释:输入的二进制串0000......
  • P6046 纯粹容器
    P6046纯粹容器关键计算ai在第i回合死的概率,并且乘上i-1,就是一个贡献值。但是直接求解在第i回合结束的概率是比较难的,因为战斗顺序是不确定的,所以不能直接求。但是可以......
  • [点分治记录] P4292 [WC2010]重建计划
    题目看到需要求的柿子首先想到分数规划。也就是二分答案,然后在check里将所有边权减去$mid$,检验是否有路经权值$\ge$0。现在问题转化成求路径长度在$[l,r]$范围内的权值......
  • 【学习笔记】分治
    分治相关的东西我基本都不会。CDQ分治最经典的分治,一般用于去掉一层偏序。对于一个区间\([l,r]\)的答案,我们可以找一个中点\(mid\),递归计算出\([l,mid]\)的答案......
  • 根号分治
    概述根号分治,是一种对数据进行分治的分治方式。具体来说,如果所要求进行的过程满足如下性质:根号以下的数据的种类很少,可以全部维护之;根号以上的数据,直接暴力的......
  • 点分治与点分树
    点分治和点分树真的是各种意义上的好东西。不仅好玩,而且写完一看自己的代码5.几kb:“wc我今天搞了好多学习”。在做关于树的题时,我们会遇到一类题型:题目跟路径有关,你找到......
  • Tree 树分治
    //题意:询问一棵树上长度不超过k的简单路径有多少条//思路:貌似可以用dsuontree但好像要用到平衡树之类的,之后再看看//https://tqltqltqlorzorzorz.blog.luogu......