莫队算法

其实莫队算法就是由暴力+分块+离线组合而成的

对于普通的暴力法来说,当其需要查找一个区间的时候,它会直接从当前区间一个个的挪动左右节点至目标区间

毫无疑问的是,这会非常的耗时间,试想一下,若一个数据先是给你(1,1)再给你(n,n)然后又给你一个(1,2)……

若是直接暴力,那么你将在前三次就要挪动约4n次左右端点,现在问题就来了,有没有更优化的方法呢?

没错,就是今天要介绍的莫队

莫队算法的核心思想就是要减少左右端点的挪移次数

那么如何减少呢?woc,这样问问题感觉好弱智啊

这里就是莫队为何是一个离线算法的原因了,它靠的就是将询问的顺序改变,来减少移动的次数

首先莫队需要将所有的询问输入,并将他们按左节点所在区间排序,当左节点所在区间一样时,则按右节点排序

注意,这里是右节点而不是右节点所在区间

对于左节点来说,他们就都在一个块里了,无论如何挪动,次数一定不会太多

对于右节点来说,在同一个块里时,总是按照递增的顺序来排列的

若是想不通的读者可按左节点为横坐标右节点为纵坐标的方式来画一个平面直角坐标系

并将每个排序后的询问在其中描点,按右节点从低到高将每一个块里的节点连接起来

每两个块之间将最高点与最低点连接起来

所消耗的费用就是这所有连线两点间曼哈顿距离之和

我不给图绝对不是因为我懒

到这里,其实莫队基本上就已经讲完了

只是还有一些因题目而变的因素:add与del函数,带不带修改,树上还是普通,回滚不回滚……

首先是两个函数,跟据题目来写,add与del函数就是用来变动当前左端点和右端点使他们变到目标左端点和右端点的工具

我在后面的题解里在说吧

其次就是带修改莫队

这玩意好难写啊

要是理解了他的思想之后也不是很难

首先是需要将刚刚所画的平面直角坐标系变为立体的

这第三维便是时间

我们根据询问的时间再执行这之前的所有修改操作

我们只需要将每一个修改的时间与原来的序列都存下来,便可以实现带修改的莫队了

详细内容也在后文再说

树上莫队吗……其实也不是特别麻烦,但作者不想写了,回滚也是,那就先这样吧

posted @ 2023-01-11 16:12  cztq  阅读(62)  评论(0)    收藏  举报