莫队算法小结以及模板题

被splay折磨了一个星期还是抄模板都wa,调试的时候查数据都发现数据太大不能查的蒟蒻杨澜决定学习莫队算法,

但是

万万没想到

莫队也到处都是坑

----------------------------------------------题记

莫队这个东西就是一个非常简♂单的类似动规的东西,也是那种不会就一直不会,一看题解秒懂的题,[虽然我看题解也半天看不懂但是只是第一道题,万事开头难嘛(也许吧)]

莫队算法是一种基于分块的离线算法,主要用来解决一些区间的询问[就是暴力],我们需要做的就是把询问都存下来然后适当的排序,分块,把内容相近的询问放在一起集中处理[利用前面得到的数据来处理询问]以节省时间...说了像没说一样..但是这个东西的原理就是酱..

 

我们先按照左端点排序,然后分块。

  然后在每个块内按右端点排序。

  然后顺序处理即可。

 

块内复杂度:

  因为块内右端点是递增的,所以右端点至多变化O(n)次,而左端点 不一定,所以是O(l*l)=O(n)次。

  块间跳转:撑死了O(n)。

  总复杂度:O(n^1.5)。

↑大神ppt里的东西复制下来了...果然比我写的清楚一万倍

那么接下来是第一题

模板题...http://www.cnblogs.com/chadinblog/p/5898011.html←lzx大神的程序和题解.第二题这里也有喵

题目 : 给定长度为n的数列以及正整数,有m个询问每次询问给定两个数l,r,求l≤i≤j≤r,且a(i) xor a(i+1) xor a(i+2) xor ... xor a(j)=k的(i,j)的个数。

输入 : 输入数据第一行为n,m,k,意义如题所示。
第二行n个正整数,第i个数表示这个数列a的第i项。
接下来m行,每行两个整数,表示询问操作的l和r。

输出 : 输出数据包含m行,表示每个询问的答案。

样例输入

6 2 3

1 2 1 1 0 3

1 6

3 5

样例输出

7

0

首先我们要回忆一下已经忘光了的位运算中异或的小知识

我们所需要的重要的一条就是,异或就是其自身的逆运算, a^b^a=b , a^a=0 , 0^a=a;

那么我们就可以用数组a[i]来储存前缀(异或)和来处理这个东西了.......

下面说的x到y的异或和的意思就是a(x) xor a(x+1) xor a(x+2) xor ... xor a(y)

↓代码的一部分

 1 p=(int)sqrt(m*1.0);
 2     for(int i=1;i<=m/p;i++){
 3         memset(cnt,0,sizeof(cnt));
 4         sort(e+(i-1)*p+1,e+i*p+1,mycmp);
 5         long long l=0,r=0,ans=0;
 6         cnt[0]++;
 7         for(int j=(i-1)*p+1;j<=i*p;j++){
 8             while(r<e[j].y)  {r++,ans+=cnt[a[r]^k],cnt[a[r]]++;}
 9 /*从异或的性质可以知道如果a[r]^k=z,那么z^a[r]=k;
10     cnt[z]指的是o∈(l,r](左开右闭是因为l声明为0...)满足从第1到第o个数的异或和是z的o有多少个...好麻烦...
11     那么为什么是+cnt[z]?
12     因为a[r]是从1到r的异或和,如果a[r]^一个1到o的异或和=k,那么从o到r的异或和就是k*/
13             while(l<e[j].x-1){cnt[a[l]]--,ans-=cnt[a[l]^k],l++;}
14             while(l>e[j].x-1){l--,ans+=cnt[a[l]^k],cnt[a[l]]++;}
15             e[j].ans=ans;
16         }
17     }

异或真是个磨人的小妖精啊![棒读]

TBC

接下来的1p应该是袜子那道题...

时间: 2024-07-31 13:51:25

莫队算法小结以及模板题的相关文章

# 莫队算法小结(待更新)

目录 莫队算法小结(待更新) 简单介绍 基础莫队 带修莫队 树上莫队 莫队算法小结(待更新) 简单介绍 博客安利: OI Wiki 大米饼 解决一类离线区间查询问题,分块思想,时间复杂度\(O(n\sqrt n)\) 排序 读入的时候对整个数组进行分块,块大小一般使用\(\sqrt n\),对询问操作排序的时候,先以块号为第一关键字,\(r\)为第二关键字,从小到大排序,然后逐个遍历 离线后将询问排序,顺序处理每个询问,暴力从上一个区间的答案转移到下一个区间的答案(通过两个指针的\(++\)和\

莫队算法小结(Markdown版)

wtf,最近挖坑有点小多啊,没办法>_<容我先把糖果公园A了再来写这个吧= =看看今天能不能A掉 好吧,我承认我第二天才把糖果公园A掉>_<下面把这篇小结补上 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m个询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为0则输出01 仔细观察发现,令x表示x这个值出现的次

莫队算法小结

唔,想有更加舒爽的阅读体验请移步http://mlz000.logdown.com/posts/252433-mo-algorithm-summary 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为则输出0/1 仔细观察发现,令x表示x个值出现的次数,则每次询问[l,r]区

HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) Problem Description The h-index of an author is the largest h where he has at least h papers with citations not les

【BZOJ3781、2038】莫队算法2水题

[BZOJ3781]小B的询问 题意:有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数 题解:初学莫队算法,差不多明白了用莫队的情况,对于这种离线的,区间长度+1时可O(1)修改答案的题,运用莫队算法是最水的 将n分成sqrt(n)块,将询问按照左端点所在的块为第一关键字,右端点的具体位置为第二关键字排序,然后用指针l,r不断暴力平移到询问的左右端点处,

信心题--FUOJ2226(莫队算法)

http://acm.fzu.edu.cn/problem.php?pid=2226 信心题,还说是信心题,题目给的真好.但是一点都不像信心题. 又是一个新的算法,莫队算法 莫队算法是一个用数组就可以轻易实现的神奇数据结构,可以处理一类无修改的离线区间查询问题(PS:暂时还没有遇到莫队解决更新区间查询的问题) 莫队算法可以在O(1),实现[l, r]到[l, r±1] / [l±1, r]的转移,然后我们就可以对所有查询分sqrt(n)块,把每个查询所在的块号当做第一关键字,右端点作为第二关键字

[voj 1551]E - Pairs 2014年武汉大学邀请赛E题 莫队算法

题目大意 有n个数,m个查询,对于每个查询,询问指定区间,有多少个数对的绝对值小于等于2. 解题思路 莫队O^1.5 首先将询问离线处理左端点进行编号,每sqrt(n)个为一组 sort结构体 当左端点编号相同时,比较右端点大小.小的放在前面. 对于每组询问暴力处理,只需处理当前新加入(删除的数字在当前区间内有多少点和它的绝对值只差小于2即可) 唯一要注意的是加点是先更新答案再计数,删点是先计数器-1再更新答案 因为对于每个询问,左端点的修改量不超过sqrt(n) 右端点每一组最坏的复杂度是修改

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题&amp;&amp;学习笔记】

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 9894  Solved: 4561[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两

莫队算法小总结 x

莫队这东西...orz 可用于解决一类可离线且在得到区间[l,r]的答案后,能在O(1)或O(log2n)得到区间[l,r+1]或[l−1,r]的答案的问题 我们先来看这样一个问题: 给出n个数字,m次询问,每次询问在区间[li,ri]之间任选两个数字相等的概率是多少.(n,q<=50000)(小z的袜子) 在区间[l,r]中,这个概率是: ∑vi=1C(2,f(i)) ----------------- C(2,r−l+1) (v表示数字值,f(i)表示数字i在区间内出现的次数) 由于没有加和