莫队算法 ( MO's algorithm )
莫队算法是由清华大学神牛莫涛发明的一种处理区间问题的离线算法
算法核心是通过先将问询区间总长度平方分块、然后将所有的问询区间按照左端点所在的块编号排序、在同一块内的则按右端点升序
然后设置左右两个下标指针、每次都移动两个指针指向问询块的左右端点、在移动的过程中不断维护答案。
可以证明原本只通过两个下标指针移动来处理问询的方法最坏可达 O(N*Q) 经过莫队算法排序后可降为 O((N+Q)*sqrt(N))
所以莫队算法其实就是排个序
当然经过我粗略的概述肯定是无法讲清楚的,这里给出几个链接方便参考和学习此算法
一些题目
分析 :
对于每个区间、实际就是查询区间逆序对的个数。
看到数据范围和不强制在线考虑使用莫队算法解决、先确定分块长度然后对所有问询进行离线排序、关键在于怎么更新。
更新算法和指针左右移动密切相关,指针的移动可以看成从 左/右 添加或者删除一个数,那么这就很好做了
在左边添加一个数、比这个数小的都贡献了一个逆序对、加上
在右边添加一个数、比这个数大的都贡献了一个逆序对、加上
在左边删除一个数、原本比这个数小的都贡献了一个逆序对、减去
在右边删除一个数、原本比这个数大的都贡献了一个逆序对、减去
注意一下左右指针移动的时候是先指针移动再更新还是先更新再移动
#include<bits/stdc++.h>
#define lowbit(i) (i & (-i))
using namespace std;
;
struct QUERY{
int L, R, Len, id;
bool operator < (const QUERY &rhs) const{
if((L/Len) == (rhs.L/rhs.Len)) return R < rhs.R;
else return (L/Len) < (rhs.L/rhs.Len);
};
}Q[maxn]; int ans[maxn];
int arr[maxn], N;
int uni[maxn], uniLen;
int Bit[maxn];
inline void BitAdd(int i, int val)
{
while(i <= N){
Bit[i] += val;
i += lowbit(i);
}
}
int BitSum(int i)
{
) ;
;
){
ret += Bit[i];
i -= lowbit(i);
}return ret;
}
int GetVal(int i)
{
int ret = lower_bound(uni, uni+uniLen, arr[i]) - uni;
return ++ret;
}
int main(void)
{
scanf("%d", &N);
; i<N; i++) scanf("%d", &arr[i]), uni[i] = arr[i];
sort(uni, uni+N);
///题目貌似没说每个元素的大小,干脆离散化好了
uniLen = unique(uni, uni+N) - uni;
int qNum, sqrt_N = (int)sqrt(N);
scanf("%d", &qNum);
; i<qNum; i++){
scanf("%d %d", &Q[i].L, &Q[i].R);
Q[i].Len = sqrt_N;
Q[i].id = i;
}
sort(Q, Q+qNum);
;
curL = , curR = ;
; i<qNum; i++){
///在左边添加一个数、比这个数小的都贡献了一个逆序对、加上
while(curL > Q[i].L){
curL--;
val = GetVal(curL-);
BitAdd(val, );
CurAns += BitSum(val-);
}
///在右边添加一个数、比这个数大的都贡献了一个逆序对、加上
while(curR < Q[i].R){
curR++;
val = GetVal(curR-);
BitAdd(val, );
CurAns += curR - curL - BitSum(val-);
}
///在左边删除一个数、原本比这个数小的都贡献了一个逆序对、减去
while(curL < Q[i].L){
val = GetVal(curL-);
BitAdd(val, -);
CurAns -= BitSum(val-);
curL++;
}
///在右边删除一个数、原本比这个数大的都贡献了一个逆序对、减去
while(curR > Q[i].R){
val = GetVal(curR-);
BitAdd(val, -);
CurAns -= curR - curL - BitSum(val-);
curR--;
}
ans[Q[i].id] = CurAns;
}
; i<qNum; i++) printf("%d\n", ans[i]);
;
}
莫队算法 ( MO's algorithm )的更多相关文章
- 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法
[题意]给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值.n,m<=5*10^4,0<=ai<=10^9. [算法]树分块+ ...
- 【BZOJ】2120: 数颜色 带修改的莫队算法
[题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...
- 「日常训练&知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)
题意与分析 题意是这样的,给定一颗节点有权值的树,然后给若干个询问,每次询问让你找出一条链上有多少个不同权值. 写这题之前要参看我的三个blog:Codeforces Round #326 Div. ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 【莫队算法模版】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 题意概括: 有 N 只袜子(分别编号为1~N),有 M 次查询 (L, R)里面随机 ...
- NBUT 1457 莫队算法 离散化
Sona Time Limit:5000MS Memory Limit:65535KB 64bit IO Format: Submit Status Practice NBUT 145 ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7687 Solved: 3516[Subm ...
- NPY and girls-HDU5145莫队算法
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...
- Codeforces617 E . XOR and Favorite Number(莫队算法)
XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: s ...
- Bzoj 2038---[2009国家集训队]小Z的袜子(hose) 莫队算法
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色 ...
随机推荐
- JS ----- 底层原理
什么是JS JavaScript是一种基于对象的动态.弱类型脚本语言(简称JS),是一种解释型语言,和其他的编程语言不同,如java/C++等编译型语言,这些语言在代码执行前会进行通篇编译,先编译成字 ...
- Mybatis--<![CDATA[ sql 语句 ]]>
在mapper文件中写sql语句时,遇到特殊字符时,如:< 等,建议使用<![CDATA[ sql 语句 ]]>标记,将sql语句包裹住,不被解析器解析 在使用mybatis 时 ...
- swagger生成文档初步使用
在大部分情况下,公司都会要求提供详细的接口文档,对于开发来说,文档有时候在赶进度的情况下,也是一件头疼的事.而swagger的自动生成文档功能,就可以帮助我们减少工作量,对于文档的修改也可以在代码中随 ...
- Editor placeholder in source code错误
When you insert code via autocompletion (or via a code snippet, sometimes), there may be placeholder ...
- [javascript基础]constructor与prototype
最初对js中 object.constructor 的认识: 在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下 ...
- AtCoder Beginner Contest 076
A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...
- django-xadmin使用
django-xadmin使用基础环境为: PS:如下环境如需升级python则先升级python,然后安装django python3.6.4安装: http://www.cnblogs.com/c ...
- 如何利用`keep-alive`按需缓存页面数据
随着项目不断变大,页面变多,搜索条件也随之也越来越多,而每次跳转页面再返回时,之前的筛选的条件都会别清空.之前在elment-ui table组件 -- 远程筛选排序提到过缓存,但是有所取巧,这次重新 ...
- centos 安装配置LAMP平台
实验环境: [root@nmserver-7 html]# cat /etc/redhat-release CentOS release 7.3.1611 (AltArch) [root@nmserv ...
- 使用layer弹窗和layui表单做新增功能
注释:代码参考http://blog.51cto.com/825272560/1891158,在其修改之上而来,在此感谢! 1.需求:使用layer在弹窗内完成新增,成功后提示并刷新页面(父页面,li ...