区间专题(一)、分块及莫队算法

邀请赛之前可能只会更这一次了吧QAQ久闻莫队算法的大名,号称是“可以解决任何区间问题”的算法,今天就来稍微说一下莫队算法。这个算法是一位名叫莫涛的国家队队长发明的算法,所以尊称为莫队算法莫队的原版文章里面的题目有一定难度,所以可以先看一下这道例题:Description    有n个数字,给出k,以及m个查询。    每次查询的格式是L,r,求L~r(左右包含)这个区间内数字的出现次数刚好是k的数...
摘要由CSDN通过智能技术生成

邀请赛之前可能只会更这一次了吧QAQ

久闻莫队算法的大名,号称是“可以解决任何区间问题”的算法,今天就来稍微说一下莫队算法。

这个算法是一位名叫莫涛的国家队队长发明的算法,所以尊称为莫队算法

莫队的原版文章里面的题目有一定难度,所以可以先看一下这道例题:

Description

    有n个数字,给出k,以及m个查询。

    每次查询的格式是L,r,求L~r(左右包含)这个区间内数字的出现次数刚好是k的数字种数。

    范围:n<=30000,k<=n,m<=30000,1<=L<r<=n,数列中元素大小<=n。

    输入n,k,m,然后n个元素,然后m行查询,对于每一个询问,输出正确的答案。

Example input:

5 2 3

1 2 3 2 2

1 2

2 4

1 5

Example output:

0

1

0

关于这道题,最直观的感觉就是暴力大法好。对于每一次询问,我们都遍历L~r的所有数字,并记录出现次数为k的数字。这样的话复杂度是O(n*m)的,肯定是过不了的。

再来看一下MyZhY提出的一种方法。

设置两个指针left和right,分别指向被查询的区间左右端点L,r,然后将这两个指针不断地移动到下一个待查区间,每次移动的时候把移动的位置上的数字出现次数+1。这么做当然是可以的,但最坏情况下,每次询问移动的大小仍有可能是n次,复杂度依旧没有改变,甚至可能更慢。

但是莫队算法就是基于这种思想实现的。莫队首先给这个序列分块。什么是分块?顾名思义就是把一个完整的序列分割成若干个大小近似相同的块,维护这些块的性质就可以了。分块的时候一般是分成√n(向上取整)个块(除了最后一个块可能不完整),这样每个块里的元素近似等于√n了。我们给这些块按左端点L排序,每个块内部按右端点排序,这样一来就会有神奇的事情发生。我们仍然考虑以上的双指针思路,并分成几种情况:

1、待查询的区间完全包含在一个块内。这样直接遍历块内的所有元素就可以了,由于最多√n个元素,所以left指针最多移动√n次,而right指针则未知,最多移动n次,故复杂度是O(n√n)

2、待查询的区间跨越了不同块。则right最多也是移动√次,由于有n个块,所以最终的复杂度也是O(n√n),而left在每一次询问下也最多移动√n次,共m√n次。

由此,该算法的总复杂度为O((m+n)√n),足以应付大部分的情况了。

总结一下,莫队算法的用途是处理一系列离线的,一般是不带修改的区间查询问题。带修改的莫队的话则需要把二元组[left,right]变成三元组[left,right,x],代表询问left到right这个区间在经过x次修改后的答案。另外还有一些什么树上莫队,草丛莫队(提莫?)之类的骚操作我也不会QAQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值