学习笔记:莫队

OK 啊,这篇重构了。

0 概念

什么是莫队
可以先去看看分块 这样就很好理解

先丢出一个问题:

  • 给出 m 个区间 l,r 求区间众数

这就是蒲公英 在线用分块可以做到 O(nn) 的复杂度
现在我们思考一下
线段树可以做什么?满足区间合并的问题
树状数组可以做什么?满足区间相减的问题
如果这两都做不了?
这下我们的乱搞神器莫队就出来了
它有 O(nn) 的优秀时间复杂度

1 普通莫队

有很多问题 每个重复求很麻烦 不妨按照一个顺序来做
根据分块的想法,分块来做每个问题。
莫队思路:首先,按 l 左端点所处在的块排序 同一块内的按右端点排序。
然后,直接按照双指针的方法爆搜问题。
这样不会 T 飞吗?
我们来分析一下时间复杂度。
不妨令块长为 S
对于跨过块与块之间的 l 端点移动,明显,它的复杂度上界为 O(n)
在同一块内,右端点是一直往后的,时间复杂度为 O(n) ,加上总共 nS 块,时间复杂度 O(n2S)
在同一块内,左端点是会乱走的,假设每次左端点乱走都跑满,那么就会遍历这块一遍。所以时间复杂度是 O(n×S)
综合一下,根据小学学的基本不等式,我们发现,在 S=n 的情况下能跑出最好的期望复杂度:O(n1.5)

然后因为因为它能暴力处理出每个点的贡献,所以是非常强大的离线工具。

2 莫队上树

直接将树转成 DFS 序乱搞即可。
如果是子树内的点, dfn 序即可搞定。
如果是一条链上的,那么我们使用 dfs 序。
什么呢?
image
dfs 序即每次在入点和出点时记录下这个点。
dfs 序有很多。
这棵树的 dfs 序其中之一为:

1,2,4,4,5,5,2,3,6,7,7,8,8,6,3,1

我们记第一次出现 x 时为 stx ,第二次出现为 edx
我们发现,一条路径可以通过讨论实现:

  • 如果 uv 中,uv 的祖先,那么只需记录下 stvstu 中只出现一次的数即可。
    证明很简单,从 stx 开始就是从已 stx 为根时遍历这棵子树,如果不是路径上的点,要么没有经过,要么经过两次。
  • 否则,从 edustv 中,记录只出现一次的点 再加上 lca 即可。
    证明也很简单,从 edu 开始往后回溯,从 ulca 的点一定记录了一次,然后再遍历子树 v,这样不会遍历到 lca ,记得加上。

这样这就是一个普通的莫队问题了。

3 莫队带修

是这样的,莫队根本不能修改。
关于修改,它像标记永久化 seg 一样 ,只能单点修改。
有些时候也可以差分,但比较少,差分后不好查询。但是异或是个例外。
然后跑三维莫队就行了,第一位修改时间,后两维表示区间。
排序优先顺序要和查询顺序相同。
这样乱搞就好了。
理论上,是取块长为 213n23t13m13 最好,时间复杂度 O(n53),但是大家都说块长取 n23 方便。

4 回滚莫队

你知道的,有些时候,增加一个数可以很容易维护,但是删一个很难维护。
举个例子,求 maxlrai ,增加一个数直接判断贡献即可。
可是删除一个数,我们发现很麻烦,用一些数据结构会增加一个 log 这是我们不想看到的。

于是 不删除莫队——回滚莫队出现了。
我们以贡献的角度考虑回滚莫队。
回滚莫队分为几个步骤:

  • 先和莫队相同的方法排序
  • 如果当前询问属于同一个块(设块长为 S)内,直接暴力,与分块思想相同。
  • 如果不属于同一块,不妨假定当前扫到块 x 。我们先设置左端点为 Rx+1(也就是什么都没有)。
  • 然后暴力拓展右端点,根据右端点是排好序的,这一步有保障。
  • 对于左端点,每次询问的时候再拓展。然后拆成三部分贡献来分别计算。
  • 最后,处理完左端点同一块内的贡献,暴力清空桶。

我们来分析一下时间复杂度。
首先,每次同块暴力时间复杂度为 O(S)
然后,对于每一块,右端点只会单独往右,时间复杂度为 O(n2S)
对于同一块内,每次左端点最多移动 O(S) 时间,所以时间复杂度为 O(mS)
之后,左端点向左移动,时间复杂度 O(n)

根据小学学的知识,假定 mn 同阶,明显,最优块长为 n 时间复杂度为 O(n1.5)
这样,我们不删莫队就搞定了!

那么不增加呢?
修改一下右端点排序,使右端点一直删,左端点为开头,也删除即可。

理论简单!

5 莫队 + bitset

有些时候我们查询一堆数加/减 能不能搞出来一个 x
我们把存在的数用 01 串表示,即存在一个位置 p ,使得 Ap=Apx=1
这时候用可以使用 bitset 优化。

每次查询时间复杂度 O(n128)
所以总的时间复杂度 O(nn+n2128)

诡异的复杂度 但是可以接受 对于某些题目

6 二次离线莫队

会填的

posted @   g1ove  阅读(29)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示