莫队算法学习小记

算法创始人

莫涛大神。

莫涛队长的算法,%%%%%%%%%

算法简介

算法前提

可以在O(1)的时间内把[l,r]的询问转移到[l-1,r],[l+1,r],[l,r-1],[l,r+1]的询问,而且不需要修改操作,那么就可以使用莫队算法([a,b]表示从a到b的区间,包含a和b)

算法核心

假如有一个询问[l,r]要转移到一个询问[l1,r1],那么需要的时间为O(|l1?l|+|r1?r|),在算法前提下,可以用这么多的时间暴力转移。

但是可以发现有时候有些点会被来回算很多次,这样大量浪费了时间,所以莫涛大神就想到了一个方法,把这些询问离线的拍一次序,让有些点可以被算的次数少一些。

l=1;r=0;\\这样初始化可以避免一些不必要的步骤。
fo(i,1,m){
    k=a[i].a;t=a[i].b;
    if(k>l)update(l,k-1,-1);\\update的1表示加,-1表示减,具体操作因题而异。
    else if(k<l)update(k,l-1,1);
    if(t>r)update(r+1,t,1);
    else if(r>t)update(t+1,r,-1);
    l=k;r=t;
}

排序的方法是分块

把序列中的所有点按照n??√来分块,然后所有询问的左端点为第一关键字,右端点为第二关键字,然后做一次双关键字排序,即可。

    fo(i,1,m){
        scanf("%lld%lld",&a[i].a,&a[i].b);
        a[i].d=(a[i].a-1)/kuai+1;\\分块
        a[i].e=(a[i].b-1)/kuai+1;
        a[i].c=i;
    }
    sort(a+1,a+1+m,cmp);

创始人的改进

因为发现|l1-l|+|r1-r|是曼哈顿距离,所以把每个的询问看作是二维平面上的一个点,然后构造最小生成树,沿着树边走即可。

一般转移只用暴力即可

很少用大神说的那么复杂的方法,正常的暴力也挺快的。

时间复杂度分析

时间复杂度为O(n1.5)

有两个角度。

角度一:看看右端点。一个块的r最多到n,每次从上一个块到达下一个块的r复杂度为n,一共有n??√个块,所以复杂度为O(nn??√)。

角度二:看看左端点。每次左端点从一个块到另一个块的复杂度为O(n??√)。在每一块中左指针的移动总量是O(Qn??√),Q是落在那个块的查询的数量。对于所有的块,总的复杂度为O(nn??√)。

所以总的复杂度为O(nn??√)=O(n1.5)

一些算法的限制

1、如前所述,该算法是离线的,这意味着当我们被强制按照特定的顺序查询时,我们不能再使用它。

2、如果有加入和删除操作的话,复杂度就会退化为O(nlognn??√)。

其余的离线题目几乎都可以做。

原始的题目:小Z的袜子(算法的第一道题——入门题)

一道莫队算法的入门题。

小Z的袜子

时间: 2024-11-09 01:54:34

莫队算法学习小记的相关文章

带修改的莫队算法学习小记

简介 莫涛大神创造出的离线询问算法的带修改版. 算法基础:需要掌握莫队算法,会打暴搜(暴力). 一个叫莫的双端队列. 只支持单点修改 操作方法 普通的不带修改的莫队算法要把每个询问带上两个关键字排序,现在待修改的莫队算法要带上三个关键字排序. 初始操作 fo(i,1,m) { scanf("%s%d%d",s,&k,&l); if (s[0]=='Q')a[++tot].l=k,a[tot].r=l,a[tot].x=num,a[tot].p=tot; else d[+

莫队算法学习笔记【BZOJ2038:小Z的袜子】【SPOJ3267:D-query】

很久以前傻乎乎地看来源奇怪的资料的时候被各种曼哈顿弄晕了. 然后现在学会的是分块方法.另新创一个分块方法. 让我们考虑这样一个区间询问问题…… 它有如下的性质: 0,n个数,Q个询问. 1,它没有修改操作,这意味着我们可以按我们喜欢的次序跟询问玩耍.实际上后面会讲到我们完全可以按任意次序玩耍. 2,如果我们知道区间询问 [L , R] 对应的值,我们可以轻易求出 [L±1 , R] 和 [L , R±1] 的值. (其实如果限制增加,比如只能求 [L+1 , R] 和 [L , R-1] 的值,

[bzoj2038]莫队算法学习

解题关键:莫队最重要的是区间之间以$O(1)$的复杂度进行转化,由于电脑原因,后续补上公式推导. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<cmath> 7 using namespace std; 8 typedef long long ll; 9 l

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并不在意两

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

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

「知识学习&amp;日常训练」莫队算法(一)(Codeforce Round #340 Div.2 E)

题意 已知一个长度为\(n\)的整数数列\(a[1],a[2],-,a[n]\),给定查询参数\(l,r\),问\([l,r]\)内,有多少连续子段满足异或和等于\(k\). 也就是说,对于所有的\(x,y (l\le x\le y\le r)\),能够满足\(a[x]\oplus a[x+1]\oplus ...\oplus a[y]=k\)的\((x,y)\)有多少组. 分析 对于这种离线区间的查询问题(不涉及对区间的更改),我们可以使用莫队算法解决.这类问题是什么类型?对于序列上的区间询问

清橙A1206 小Z的袜子(莫队算法)

A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB 总提交次数:744   AC次数:210   平均分:44.44 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2010中国国家集训队命题答辩 问题描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是

莫队算法小结以及模板题

被splay折磨了一个星期还是抄模板都wa,调试的时候查数据都发现数据太大不能查的蒟蒻杨澜决定学习莫队算法, 但是 万万没想到 莫队也到处都是坑 ----------------------------------------------题记 莫队这个东西就是一个非常简♂单的类似动规的东西,也是那种不会就一直不会,一看题解秒懂的题,[虽然我看题解也半天看不懂但是只是第一道题,万事开头难嘛(也许吧)] 莫队算法是一种基于分块的离线算法,主要用来解决一些区间的询问[就是暴力],我们需要做的就是把询问

莫队算法~讲解

用了大约1h搞定了基础的莫队算法.写篇博客算是检验下自己的学习成果. 一.什么是莫队算法? 莫队算法是用来处理一类无修改的离线区间询问问题.——(摘自前国家队队长莫涛在知乎上对莫队算法的解释.) 莫队算法是前国家队队长莫涛在比赛的时候想出来的算法. 传说中能解决一切区间处理问题的莫队算法. 准确的说,是离线区间问题.但是现在的莫队被拓展到了有树上莫队,带修莫队(即带修改的莫队).这里只先讲普通的莫队. 还有一点,重要的事情说三遍!莫队不是提莫队长!莫队不是提莫队长!!莫队不是提莫队长!!! 二.