莫队算法

这名字···

这个算法是由之前的国家队队长莫涛巨神(Orz….%%% 64 )发明的,所以尊称莫队算法。

莫队算法

事实上,莫队算法这种东西,应该叫做——

一个优雅的暴力(引自Alan_Cty)

传说中能解决一切区间问题的算法

如果我们知道区间 [L,R] ,就能在O(1)求出 [L1,R],[L+1,R],[L,R1],[L,R+1] 的话,那就可以用莫队算法了。

有一种经典的问题:给你一些不带修改的区间询问,要求快速回答

显然,有一些我们可以通过线段树来完成,因为线段树是 O(NlogN)

但是,线段树有的东西是维护不了的。

看一个例子

给你一个数列,若干询问,要求回答区间内同种颜色大小。

线段树很难做,怎么办?

用莫队算法!

莫队算法的实质是通过将询问排序,每个询问均由前一个询问(排序后的)转移得来,通过一定的排序优化时间复杂度。往往可以有 O(NN) 的效果

回到题目
显然对于两次询问 L,R L,R ,知道了 L,R 的答案,就可以暴力计算 |LL|+|RR| 次得出 L,R 的答案。

|LL|+|RR| 。这个东西,数学上称之为曼哈顿距离

把每个询问看作是二维平面上的点,那么我们的最小总时间,就是这些点的最小曼哈顿距离生成树, 按照这个树的顺序做,复杂度变成了 O(NN) (为什么?不好意思,我不会证),而且这个生成树连边也有特别的技巧,可以去看莫队在知乎上推荐的那篇。

然而这样有一点猥琐

有一个优美方便简洁好理解的替代品

分块大法好!

把整个序列分块,把 L 按照所在块的顺序为第一关键字,把 R R 本身!)为第二关键字排序。

为什么要分块不能直接排呢?

分块很好的减少了一种情况的影响。

L<L<L ,并且距离很近,但是 R<R<R ,并且 R 与另外两个离得很远。如果直接按 L 排序就会浪费非常多的时间。

由于每个块的大小是 N

分块使得两个询问之间差异平均到了 L,R 上。

因此,理论复杂度大约是 O(NN) ,实际上是 O( 玄学??跑的过就行 )

带上了修改,怎么办?

然后我们继续分块。

把二元组 L,R 变成三元组 L,R,x x 是这次询问在修改第几次后。

然后把 R 所在块看作第二关键字, x 看作第三关键字排序即可。

转移时直接恢复(或删除)两次询问之间的修改。如果在区间内还要计算对答案的影响

然而修改的复杂度十分神奇,是 O(N53) ,且最优分块方式是每块 N23

复杂度的证明可以看看a_crazy_czy的博客

有一道板题
http://blog.csdn.net/hzj1054689699/article/details/51880644

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值