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

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

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

可以证明原本只通过两个下标指针移动来处理问询的方法最坏可达 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. [Vuejs] 点击单选框触发两次点击事件的处理

    <el-radio-group v-model="uploadStatus" class="upload-status-radio"> <el ...

  2. vue ----》实现打印功能

    1.安装打印相关依赖 cnpm install vue-print-nb --save 2.安装后,在main.js文件中引入 import Print from 'vue-print-nb' Vue ...

  3. 第六周作业&实验报告四

    一.实验目的 (1)掌握类的继承 (2)变量的继承和覆盖,方法的继承,重载和覆盖的实现: 二.实验的内容 (1)根据下面的要求实现圆类Circle. 1.圆类Circle的成员变量:radius表示圆 ...

  4. nodejs 写服务器解决中文乱码问题

    nodejs 写服务器解决中文乱码问题:https://blog.csdn.net/worldmakewayfordream/article/details/77483423     本文链接:htt ...

  5. Microsoft BarCode Control 16.0属性

    Labview(2018)可通过Active调用Microsoft BarCode Control 16.0来生成条形码, 参考资料如下: 生成效果: 二维码: 条形码: 执行程序发现修改线条宽度不影 ...

  6. 记一次程序从x86_64linux平台移植到armv7平台

    前言 最近接了个任务,需要把代码移植到armv7平台,搜寻相关方法,了解到可以利用交叉编译工具如:gcc-linaro-arm-linux-gnueabihf.把自己依赖的第三方库代码和自己代码分别编 ...

  7. CF 1136C Nastya Is Transposing Matrices

    题目链接:http://codeforces.com/problemset/problem/1136/C 题目分析 看了题目之后,第一想法:任意位置都可以倒置,要是枚举,铁定的超时.所以需要探索规律. ...

  8. python 链接mysql 修改查询删除语句

    import mysql.connector.pooling config = { "host": "localhost", "port": ...

  9. 机器学习-SVM中的SMO算法详解

  10. vue报错——Module not found: Error: Can't resolve 'less-loader sass' in ...

    npm install sass-loader -D npm install node-sass -D