莫队算法讲解(含树上莫队)

本文详细介绍莫队算法的基本原理和实现步骤,包括如何通过更改询问操作的执行顺序来提高效率,适用于离线处理的问题。此外还介绍了树上莫队算法及带修改的莫队算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

莫队算法

莫队算法是一种离线算法通常不能有修改 操作。
其通过对询问操作的执行顺序进行更改,然后使用最暴力的方法,可以达到很好的复杂度。

首先,如果要用莫队算法,则必须满足已知ans[l,r]可以得到ans[l+1,r],ans[l-1,r],ans[l,r+1],ans[l,r-1]。

莫队算法的实现步骤为:
1、先对原序列进行分块。
2、离线操作,对询问进行排序,以左端点所在块编号第一关键字,右端点的位置第二关键字,进行排序。然后维护[l,r]的答案,并不断调整lr

我们来分析一下时间复杂度:
1、左端点所在块编号确定时,右端点位置单调不下降,所以右端点移动最多造成的时间复杂度是O(n)的,总共n块,总时间复杂度为O(nn)。

2、左端点所在块编号进行变动时,右端点移动最多造成的时间复杂度是O(n),总共n块,变动次数也就是n次,总时间复杂度为O(nn)。

3、块内左端点位置每次最多移动n,一共m次询问,也就是一共移动m次,总时间复杂度为O(mn)。

总的来说,时间复杂度是32次的,这是十分优秀的。

树上莫队

树上莫队是莫队算法的拓展,思想依然差不多,下面我介绍一种树上莫队的做法。

首先弄出树的括号序。(对树做一次深搜,第一次进入某节点时,将此节点编号加入序列,从某节点退出时,将此节点编号第二次加入序列)
如图,有一棵树,以及它的括号序:

树上莫队分析

然后记录一个数在括号序中第一次出现和最后一次出现的位置。
如果要询问jk之间路径的信息,需进行分类讨论:
(以下均遵循此原则,出现两次的数字不算入所求信息中)
1、如果jk的祖先,那么所求信息就为jk最后出现的位置之间的信息。
2、如果j不是k的祖先。那么所求信息就为j最先出现的位置以及k最后出现的位置之间的信息,我们发现,j,klca不在其中,再把lca加上即可。

那么实现的时候就是用cha来表示一个点的出现情况的改变。
然后当做序列上的莫队来做就可以了。

拓展:带修改的莫队

其实莫队还是可以带修改的。O(∩_∩)O~~
带修改的莫队其实也不难,我们三元组(l,r,x)来排序,x表示在此次询问操作之前经过了x次修改操作。同样的,知道(l,r,x)的答案可以知道(l-1,r,x)(l+1,r,x)(l,r-1,x)(l,r+1,x)(l,r,x-1)(l,r,x+1)的答案,一样可以用莫队算法。

块大小需要设置为n23,总时间复杂度是O(n53),证明略。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值