ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

莫队

2022-06-18 18:35:43  阅读:190  来源: 互联网

标签:分块 值域 sqrt 端点 quad 莫队


\(\quad\)对于莫队的复杂度计算,我们首先块长,然后分别分析左右端点的移动,然后就会得到一个式子,为了使这个式子最小,适当调整分块块长即可。

普通莫队

\(\quad\)对于普通莫队,一般的复杂度是 $O(n\sqrt n) $ 。

\(\quad\)最优的分块方式是对于端点分块,块长为 \(\frac{n}{\sqrt m}\) ,然后以左端点的块为第一关键字,右端点的块为第二关键字,同时实行奇偶排序,就是对于第二关键字,如果第一关键字是奇数块那么从左到右排,否则从右到左排。

Luogu P1494 [国家集训队] 小 Z 的袜子

带修莫队

\(\quad\)带修莫队就是加一个时间轴,唯一要注意的是每次滚时间轴的时候要把时间轴记录的改变值和当前值互换一下,这样再滚回去的时候就可以还原之前的值。一般块长为 \(O(n^{\frac{2}{3}})\)

P1903 [国家集训队] 数颜色 / 维护队列

回滚莫队

\(\quad\)对于一类很像莫队,但是它在指针移动的时候只能考虑增/减的贡献,这个时候,就需要用回滚莫队

\(\quad\)假设只能增,那么排序的时候,以左端点的块为第一关键字,右端点的 为第二关键字升序排序,那么对于左端点在同一块的我们一起考虑。对于左端点在一个块中的区间,我们每次让左端点赋初值为当前块的右端点+1 ,右端点因为是递增的,所以可以直接一直扫下去,那么最后分析复杂度仍然是 \(O(n\sqrt m)\) ,至于只能减的情况,其实是一样的。

P5906 【模板】回滚莫队&不删除莫队

莫队套值域分块

\(\quad\)值域分块就是在值域上分块,做到 \(O(1)\) 插入,\(O(\sqrt S)\) 查询,和莫队简直是天作之合。

P3709 大爷的字符串题

\(\quad\)贪心的来看就是最多的上升子序列的个数,这个个数一定大于等于区间众数的个数,这个显然,事实上可以构造成区间众数的个数,所以就是要求区间众数的个数。这个东西就可以用莫队套一个值域分块。

\(\quad\)不过事实上我第一眼看这个题,觉得是回滚莫队。而事实上求区间众数这种只能加不能减的题,确实是可以用回滚莫队做。

莫队二次离线

\(\quad\)有这么一类莫队的题目,它的每次转移做不到 \(O(1)\) ,这个时候就需要二次离线。

\(\quad\)莫队本身是第一次离线。

\(\quad\)对于每次转移会有一个状态表达式,如果能 差分 的话,就可以转换成两个有关前缀和查询的东西,我们将这个东西存下来,也就是 二次离线 ,最后再扫一遍,求解即可。

\(\quad\)注意为了保证总体的复杂度仍然为 \(O(n\sqrt n)\) ,最后扫一遍时也要保证是这个复杂度。但因为移动的次数就有这个复杂度了,所以我们需要 \(O(1)\) 处理离线下来的操作,又因为只有 \(O(n)\) 的插入,我们完全可以套个根号,于是我们经常用值域分块来中和这里的复杂度。

P4887 【模板】莫队二次离线(第十四分块(前体))

P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II

\(\quad\)套个值域分块扫就可以了,每一个块维护比自己小的值的个数,在块的内部维护一个数组表示在块内比自己小的数的个数。

P5501 [LnOI2019]来者不拒,去者不追

\(\quad\)这个题目似乎是上面题目的姊妹题,维护比一个数大的数的和,仍然用值域分块维护即可。

树上莫队

\(\quad\)似乎是有两种写法,一种是直接在树上分块,一种是转换成欧拉序,然后转换成序列上的操作,个人认为第二种应该好理解,于是写的第二种。

P4074 [WC2013] 糖果公园

\(\quad\)这是个带修树上莫队板子。

莫队套 bitset

\(\quad\)这个东西可以解决一类的计数问题,比如有关区间数的次数的问题,可以考虑用 bitset 压位乱搞。常用的 bitset 语法:

bit.count() //返回 1 的个数
bit.any() //返回是否有 1
bit.set() //全部变成 1
bit.set(p) //将第 p+1 位变成 1 (bitset 是从 0 位开始的)
bit.set(p,x) //将第 P+1 为变成 x
bit.reset() //全部变成 0
bit.reset(p) //将第 p+1 位变成 0

P4688 [Ynoi2016] 掉进兔子洞

\(\quad\)首先离散化一下,答案就是总的长度和减去交集的长度乘 3 ,于是我们就是要求三个区间数的交集的个数。因为只有 n 个数字,所以对每一个数字离散化一下,这样在 bitset 中就会有对应的位置。每次莫队记录一下每一个数的个数,然后在 bitset 里面实现修改操作,最后取个并即可。

P5355 [Ynoi2017] 由乃的玉米田

\(\quad\)对于值域维护两个 bitset ,对于每个数 x ,则 b1.insert(x),b2.insert(N-x) ,那么对于加减就好说了,对于乘直接枚举根号一下的数,对于除要分类处理。

\(\quad\)对于除,如果 \(x\leq \sqrt n\) ,我们单独预处理一下。考虑枚举 x ,然后扫描线们对于每个位置维护这个位置及之前能做贡献的一对数左边的数最大的位置,假设为 tp[x],那么同时要维护一个 pre[x] 表示上一次出现 x 的位置,那么对于一个区间则当 tp[q[i].r]>=q[i].l 时满足条件。对于 $x\geq \sqrt n $ ,就直接枚举它的倍数就可以了。

标签:分块,值域,sqrt,端点,quad,莫队
来源: https://www.cnblogs.com/kzos/p/16388944.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有