莫队算法是由清华大学神牛莫涛发明的一种处理区间问题的离线算法

算法核心是通过先将问询区间总长度平方分块、然后将所有的问询区间按照左端点所在的块编号排序、在同一块内的则按右端点升序

然后设置左右两个下标指针、每次都移动两个指针指向问询块的左右端点、在移动的过程中不断维护答案。

可以证明原本只通过两个下标指针移动来处理问询的方法最坏可达 O(N*Q) 经过莫队算法排序后可降为 O((N+Q)*sqrt(N))

所以莫队算法其实就是排个序

当然经过我粗略的概述肯定是无法讲清楚的,这里给出几个链接方便参考和学习此算法

莫队算法还是莫队算法当然还是莫队算法

一些题目

BZOJ Mato的文件管理

分析 :

对于每个区间、实际就是查询区间逆序对的个数。

看到数据范围和不强制在线考虑使用莫队算法解决、先确定分块长度然后对所有问询进行离线排序、关键在于怎么更新。

更新算法和指针左右移动密切相关,指针的移动可以看成从 左/右 添加或者删除一个数,那么这就很好做了

在左边添加一个数、比这个数小的都贡献了一个逆序对、加上

在右边添加一个数、比这个数大的都贡献了一个逆序对、加上

在左边删除一个数、原本比这个数小的都贡献了一个逆序对、减去

在右边删除一个数、原本比这个数大的都贡献了一个逆序对、减去

注意一下左右指针移动的时候是先指针移动再更新还是先更新再移动

#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 )的更多相关文章

  1. 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法

    [题意]给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值.n,m<=5*10^4,0<=ai<=10^9. [算法]树分块+ ...

  2. 【BZOJ】2120: 数颜色 带修改的莫队算法

    [题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...

  3. 「日常训练&知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)

    题意与分析 题意是这样的,给定一颗节点有权值的树,然后给若干个询问,每次询问让你找出一条链上有多少个不同权值. 写这题之前要参看我的三个blog:Codeforces Round #326 Div. ...

  4. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 【莫队算法模版】

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 题意概括: 有 N 只袜子(分别编号为1~N),有 M 次查询 (L, R)里面随机 ...

  5. NBUT 1457 莫队算法 离散化

    Sona Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format: Submit Status Practice NBUT 145 ...

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

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Subm ...

  7. NPY and girls-HDU5145莫队算法

    Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

  8. Codeforces617 E . XOR and Favorite Number(莫队算法)

    XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: s ...

  9. Bzoj 2038---[2009国家集训队]小Z的袜子(hose) 莫队算法

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色 ...

随机推荐

  1. C语言Ⅰ博客作业05

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9827 我在这个课程的目 ...

  2. c语言1作业07

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-4/homework/9932 我在这个课程的目 ...

  3. python​日记:优化(SEO)狗学Python的日子(1)

    一名优秀的程序员,在穿越单行道时也会确认双向的来车情况 ——道格拉斯.林德(Doug Linder) 大家可能好奇Python是什么东东,今天是小猿开始学习Python的第一天.周五在公司的时候收到了 ...

  4. python基础预习小结

    一.执行python程序的两种方式 1.1 交互式 在终端内输入python3,然后输入python代码 1.2 命令式 在终端内输入python3文本文件路径 二.执行python的两种IDE 2. ...

  5. npm学习(八)之如何使用语义化版本

    npm的语义化版本控制——Semantic versioning 在新发布的代码中传达更改的程度非常重要,因为有时更新会破坏包需要的代码(称为依赖项).语义化版本控制(semver)是一个旨在解决这个 ...

  6. CNN与图像高级应用

    一.图像识别与定位 思路1:视作回归 4个数字,用L2 loss/欧氏距离损失(x,y,w,h)这四个数都是连续值 思路2:借助图像窗口 二.物体识别 0.图像识别与定位: (1)Classifica ...

  7. 请求转发forward()和URL重定向redirect()的区别

  8. 多层 iframe 嵌套 js 方法调用

    一下午一个这破问题,浪费了不少时间,怎么也实现不了我的上上级iframe 刷新.NND. 实现了,记录一下下吧: window.parent.parent.document.getElementByI ...

  9. docker 开启特权模式

    可以在创建容器时通过 --privileged=true 开启特权模式. 创建容器: # docker run -d --name centos7 --privileged=true centos7: ...

  10. 有准备的面试才能拿到更好的 Offer

    http://www.sohu.com/a/331411917_181657 前几天有读者问我,工作不顺利辞职了.本来以为凭借自己的能力和工作经验可以轻松找到更好的工作,结果投了简历,约面试的很少,面 ...