莫队算法学习笔记

news/2025/2/22 19:22:16/文章来源:https://www.cnblogs.com/wusixuan/p/18731052

莫队算法的发明者是一个叫做 莫涛 的人,所以被称为莫队算法,简称莫队

英语 Mo's algorithm

使用场景

莫队算法常常被用来处理多次区间询问的问题,离线处理询问(必须满足!!!)。

插叙:离线是一种得到所有询问再进行计算的方法,是很重要的思想。

对于这种“区间询问”的问题,我们现在就已经可以使用好几种方法:甚至还可以维护修改的线段树、树状数组(不过使用场景有限),以及同样可以很快解决问题的 ST 表……

所以,莫队在很多时候可以被其他算法代替。但是莫队也有很多“专利”,就像分块可以解决很多线段树解决不了的问题(虽然就是慢了点)。

树状数组需要可以区间减法,线段树和 ST 表需要可以区间合并而莫队需要可以进行区间扩张和区间缩短。

题外话:区间扩张和区间缩短你能想到什么?没错,尺取法。

算法思路

我们不妨解决一个问题,从问题中了解算法的大体思路。

问题:询问区间和。(这显然可以使用前缀和进行维护,但是我们假装不会这个

法一纯暴力。枚举区间内所有的数,加起来即可。 时间复杂度 \(O(qn)\)

不再阐述。

法二另一种暴力。方法如下。

假设我们现在已经计算出了 \([l_1,r_1]\) 的区间和,而现在又需要计算 \([l_2,r_2]\) 的区间和。

出于懒的本性,我们考虑在原 \([l_1,r_1]\) 的区间和上动一些手脚

直接将 \(l_1\) 移到 \(l_2\),然后将 \(r_1\) 移到 \(r_2\),顺便维护一下即可。

复杂度仍然是 \(O(qn)\),好像没有优化多少。

好像比上面的方法还要蠢,但是不必灰心,这种“蠢”的方法正是莫队的起源。

法三莫队。对询问进行了顺序调整,然后使用法二的方法处理即可。

先对询问的序列按照左边界的值分成了 \(\sqrt(n)\) 个块长为 \(\sqrt(n)\) 的块(好奇怪)。

然后对询问排序:

  • 第一关键字:按左边界的块号从小到大排序。(啊?)

  • 第二关键字:按右边界从小到大排序。


看起来非常古怪的一个排序,那么这个排序有什么奇效呢?我们来举个例子。

\(n=9,q=10\)

我们有如下查询:\([2,5],[4,5],[5,9],[1,6],[2,3],[7,8],[9,9],[6,7],[2,8],[3,4]\)

而我们按照块号排序之后变成了 \([2,3],[3,4],[2,5],[1,6],[2,8],[4,6],[6,7],[5,9],[7,8],[9,9]\) 这个样子。

然后我们画一个图,来使用平面直角坐标系来绘出这些区间(左端点变成了横坐标,右端点变成了纵坐标)。

解释一下图片的含义:

为了便于描述,我们先设一开始的区间在 \([0,0]\) 的位置。

因为第一关键字使用块号来排序,所以同一个块内的点一定在一起,已经使用粗的红线分割出三个块(\(\sqrt(9)=3\))。

我们使用蓝色边来体现块内结点移动,然后使用橙色边来体现块间结点的移动。

容易知道,块的数量是 \(O(\sqrt(n))\) 个,而块的横坐标长度是 \(\sqrt(n)\)(注意,这里的每一个点的横纵坐标均不可能超过 \(n\),这可是查询)。

因为橙色边的数量和块的数量有关,所以橙色边的数量最多是 \(O(\sqrt(n))\)个,而每一次点之间移动的复杂度不超过 \(n\)(这是区间移动,左端点和右端点总共最多移动 \(n\) 下)。

因此,单算橙色边,时间复杂度为 \(O(n \sqrt(n))\)


橙色边分析的落脚点在于原区间的移动,考虑使用 抽象之后的点之间的移动 来分析蓝色边的复杂度。

显然,点之间的移动 的次数取决于两点之间的纵坐标和横坐标差。

考虑纵坐标。因为第一关键字在块内中已经失去了作用,而第二关键字保证了我们在块内一定是越爬越高。

而每一个点的横纵坐标均不可能超过 \(n\),所以单个块内纵坐标总共也只会对时间造成 \(n\) 的影响。

所有的块的纵坐标影响合起来,也只有 \(O(n \sqrt(n))\),可以接受。

考虑横坐标。根据前文,每一个块的横向长度都不可能超过 \(\sqrt(n)\),所以横坐标的块内单次只会造成 \(\sqrt(n)\) 的时间影响。

而总共有 \(q\) 个点,相乘起来,\(O(q \sqrt(n))\),仍然可以接受。


经过上面的分析,你现在知道为什么这样排序了吧!

实际上,所有的看起来古怪的算法,都是为了以后恰到好处的运用

综上所述,莫队的时间复杂度为 \(O((q+n) \sqrt(n))\)。排序是 \(O(n\log n)\) 的,但是相比 \(\sqrt(n)\) 来说还是可以忽略的。

这就是莫队的想法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888103.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

参数-返回值-局部变量-数组

参数和局部变量没有本质区别,都是栈中的数据 参数时在函数调用前分配的值,局部变量是在函数调用时分配的值 参数 ebp+* 局部变量 ebp-* 赋值的本质是把运算结果放到某个内存里数组: 一堆连续存储的等宽数据

详细介绍java的线程池状态

一、详细介绍java的线程池状态 Java 中的线程池状态是 ThreadPoolExecutor 类内部管理的一个重要概念。线程池的状态决定了线程池的行为,例如是否接受新任务、是否处理队列中的任务、是否中断正在执行的任务等。 线程池的状态通过一个 AtomicInteger 变量(ctl)来表示,该变量…

[Java SE] Java静态代码块与静态属性的执行顺序

序 重要结论先说结论,再去观察实验现象,印证结论。静态变量初始化和静态代码块的执行顺序是:按照它们在类中出现的顺序进行的。代码实验 实验1import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class JavaStaticTest {private final static String VAR = &qu…

PyTorch TensorBoard 使用

这篇文章介绍如何在 PyTorch 中使用 TensorBoard 记录训练数据。 记录数据 初始化 在程序启动时创建 SummaryWriter 对象用于写入日志数据。 from torch.utils.tensorboard import SummaryWriter import datetime# 获取当前时间戳,一般以时间戳作为记录文件夹名称的一部分 tim…

Svelte 最新中文文档教程(16)—— Context(上下文)

前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

微信小程序-授权获取手机号

前端 wxml <button name=phone class=phone value={{userInfo.phone}} wx:if="{{!userInfo.phone}}" bindgetphonenumber="getPhoneNumber" hover-class=none open-type=getPhoneNumber>点击获取 </button>js import { wxGetPhoneNumber } fr…

Linux 中xargs 中 -L和-n参数的差异

001、-L :按照换行符的数量来传递[root@PC1 dir1]# ls [root@PC1 dir1]# echo {0..9} 0 1 2 3 4 5 6 7 8 9 [root@PC1 dir1]# echo {0..9} | xargs -L 2 ## 利用echo生成一个1行的测试数据 0 1 2 3 4 5 6 7 8 9 [root@PC1 dir1]# seq 0 9 0 1 2 3 4 5 6 7 8 9 [ro…

【humanoid gym】关于在Issac gym里面PPO算法实现里transitions部分roll out storage的记录

1. 前言 一方面便于日后自己的温故学习,另一方面也便于大家的学习和交流。 如有不对之处,欢迎评论区指出错误,你我共同进步学习! 2. 正文 2.1 在on_policy_runner.py文件夹下,初始化的地方:然后我们寻找定义的地方,在ppo.py文件夹下:其中参数num_transitions_per_env其…

Windows快速部署xxl-job.jar

1.在官网下载文件 https://gitee.com/xuxueli0323/xxl-job 2.在idea打开项目 3.修改maven版本,当前版本(2025/2/22)需要使用maven3.6.3+,maven地址:https://maven.apache.org/download.cgi maven版本过老的报错信息:Failed to execute goal org.apache.maven.plugins:mav…

复制浏览器网页文字 粘贴时却乱码的解决

本文介绍在复制网页内容后粘贴时,粘贴内容出现一个方框图案而不是当初复制内容的解决办法~本文介绍在复制网页内容后粘贴时,粘贴内容出现一个方框图案而不是当初复制内容的解决办法。最近,需要将谷歌地球引擎(Google Earth Engine,GEE)网页中的一段代码复制到另一个网页中…

【翻译】凝视深渊:千核并发控制的评估

凝视深渊:千核并发控制的评估 作者 Xiangyao Yu MIT CSAIL yxy@csail.mit.edu George Bezerra MIT CSAIL gbezerra@csail.mit.edu Andrew Pavlo 卡内基梅隆大学 pavlo@cs.cmu.edu Srinivas Devadas MIT CSAIL devadas@csail.mit.edu Michael Stonebraker MIT CSAIL stonebrake…

2.21课堂测验

需求描述: 请设计一个仓储管理系统原型系统,该系统支持多个仓库的设立。统一设立物资台账,物资台账需包含物资编码、物资名称、规格、材质、供应商、品牌、物资分类,用户可以自定义物资的物资分类。需限制不同的物资名称、规格、材质的物资不能设立相同的物资编码。仓库人员…