莫队算法 ( 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每天早上都要耗费很久从一堆五颜六色 ...
随机推荐
- 【VS开发】DLL和ocx的区别
ActiveX,OLE是基于COM的一种应用,其文件后缀一般以dll和ocx结尾:ocx作为一种特殊的dll文件,具有一定的用户界面和事件响应,而dll文件只是方法和属性的集合. 一.关于DLL的介绍 ...
- python 并发编程 多线程 event
event实现了一个线程通知另外一个线程 线程的一个关键特性是每个线程都是独立运行且状态不可预测. 1.为什么要使用Event对象: 如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的 ...
- Redis数据类型Strings、Lists常用操作指令
Redis数据类型Strings.Lists常用操作指令 Strings常用操作指令 GET.SET相关操作 # GET 获取键值对 127.0.0.1:6379> get name (nil) ...
- bi的tableau
参考: 官网: https://help.tableau.com/current/server-linux/zh-cn/get_started_server.htm 可视化分析最佳做法: 实用指南 h ...
- AKKA学习(二) 未完
Actor调用 从上面的例子中,我们可以大概的对AKKA在JAVA中的使用有一个全局的概念.这里我们在稍微细致的讲解一下. 在JAVA中使用AKKA进行开发主要有这几个步骤: 定义消息模型. 创建Ac ...
- MySQL-4- 索引及执行计划
1. 索引作用 提供了类似于书中目录的作用,目的是为了优化查询 2. 索引的种类(算法) B树索引 Hash索引 R树 Full text GIS 3. B树 基于不同的查找算法分类介绍 B-tr ...
- Solution for automatic update of Chinese word segmentation full-text index in NEO4J
Solution for automatic update of Chinese word segmentation full-text index in NEO4J 1. Sample data 2 ...
- C#/.NET/.NET Core定时任务调度的方法或者组件有哪些--Timer,FluentScheduler还是...
原文:C#/.NET/.NET Core定时任务调度的方法或者组件有哪些--Timer,FluentScheduler还是... 原文由Rector首发于 码友网 之 <C#/.NET/.NET ...
- Android应用安全开发之源码安全
Android应用安全开发之源码安全 gh0stbo · 2016/01/21 10:24 0x00 简介 Android apk很容易通过逆向工程进行反编译,从而是其代码完全暴露给攻击者,使apk面 ...
- 雪花算法生成ID
前言我们的数据库在设计时一般有两个ID,自增的id为主键,还有一个业务ID使用UUID生成.自增id在需要分表的情况下做为业务主键不太理想,所以我们增加了uuid作为业务ID,有了业务id仍然还存在自 ...