莫队算法

深夜来放毒,哈哈,闲着没事看了一下收藏里面的文章,莫队算法应该是放了很久了,但是都不想看(其实是看不懂),zz。

为了清空一下收藏夹,于是印着头皮看了一下莫队算法,一篇好的讲解是多么的重要的。看了好几篇,首先文章的排版我就不想看了

推荐好文->莫队算法讲解    这是一篇博客的译文 原文


主要思想在于:对于离线查询,按照朴素的思想复杂度为O(n^2),但是莫队算法的厉害之处在于只是改变查询的顺序而已。一开始不太看得懂,看了两三篇基本能够明白了。

重点:

(1)是分块思想,将结点分块,然后排序,第一顺序是左区间L,按照所处的块来区分,第二顺序是右区间R,按照大小来排序。

(2)设计add,remove函数,不同的问法设计不同,主要的修改地方是这两个函数。

(3)就是左右区间的移动了,4个循环目的是使得currentL和currentR到达查询的位置L和R,算法的高效就在于移动的次数,通过调整顺序,使得移动的次数在O(n*sqrt(n))。


add(position):
  count[array[position]]++
  if count[array[position]] == 3:
    answer++

remove(position):
  count[array[position]]--
  if count[array[position]] == 2:
    answer--

currentL = 0
currentR = 0
answer = 0
count[] = 0
for each query:
  // currentL should go to L, currentR should go to R
  while currentL < L:
    remove(currentL)
    currentL++
  while currentL > L:
    add(currentL)
    currentL--
  while currentR < R:
    add(currentR)
    currentR++
  while currentR > R:
    remove(currentR)
    currentR--
  output answer

由于好久好久没有写过C++了,现在也没时间刷题。所以只是了解一下思想而已,至于练手还是以后吧。

下面的一些相关的题:

习题和示例代码

DQUERY – SPOJ:区间内不同元素的数量=出现次数>=1的元素个数,所以跟以上讨论的问题是一样的。 
点击此处查看示例代码 
注意:该代码提交会超时,加上更快的输入输出(传说中的输入输出挂?) 就能AC。为了使代码整洁,去掉了快的输入输出。(评论中说将remove 和add 声明为inline内联函数就可以AC。) 
Powerful array – CF Div1 D: 这道题是必须用莫队算法的例子。我找不到任何其它解法。 CF Div1 D 意味着这是一道难题。看看用了莫队算法就多简单了。 你只需要修改上述代码中的add(), remove() 函数。 
GERALD07 – Codechef 
GERALD3 – Codechef 
Tree and Queries – CF Div1 D 
Powerful Array – CF Div1 D 
Jeff and Removing Periods – CF Div1 D 
Sherlock and Inversions – Codechef

参考链接: 点击打开链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值