莫队-一个让查询的高效的方法-并不深刻的讲解文章-但是易懂!

说在前面:

  • 莫队算法只能用于离线查询:什么是离线查询,就是输入了查询的区间,不用立即给出答案,可以在所有的区间都输入完毕之后统一的给出答案
  • 要是我们用最笨的方法:就是直接计算相应的区间和,那离线的优势你就没有用到
  • 另一种方法:
    这个就是另一种方法
  • 但是这种方法有个漏洞:
    要是左右横条太剧烈,那就很难受,因为每次都是一步一步跳那么多次,失去了优势
    在这里插入图片描述
  • 能不能有一种查询顺序让左右横条少点了

莫队

  • 我们把要查询的 L R 区间存起来,排个序
    要是按照L 排序,那么极端情况就是R 从最右到最左再到最右,一直这样
  • 我们按照R 排序,同理
  • 莫队结合了块的思:
    L 所在块为第一关键字
    R 的位置就第二关键字在这里插入图片描述
    假设 按序号(id)1 2 3 的顺序查询
    我们排个序变成了 2 1 3
    但是我们输出的时候不能按照 2 1 3 的循序输出,所以要记录我们的最开始 的 循序 也就是id 为 1 2 3
    在这里插入图片描述
    要是再加上序号4:
    循序就是2 1 3 4 的循序,但是还是要记录id
    这就是莫队算法的过程。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int sizen;
struct node{
    int l,r,id;

    bool operator < (const node & n) const {
        if(l/sizen==n.l/sizen)return r<n.r;
        else return l/sizen< n.l/sizen;
    }
}q[maxn];
int n,m;
int data[maxn];

int Ans[maxn];
int ans;
void add(int n){
}
void sub(int n){
}
main(){
    cin>>n>>m;
    for(int a=0;a<n;a++){
        cin>>data[a];
    }
    for(int a=0;a<m;a++){
        cin>>q[a].l>>q[a].r;
        q[a].id=a;
    }
    sort(q,q+m);
    /// 首先要定义当前的 L R
    /// 初始化的时候要是空集 也就是什么也不包含
    ///  L 比 R 还 右 就是什么也不包含,但是只要一个动了,就包含了一个;
    int l=1;
    int r=0;

for(int a=0;a<m;a++){
    while(l<q[a].l)sub(l--);
    while(l>q[a].l)add(--l);
    while(r<q[a].r)add(++r);
    while(r>q[a].r)sub(r++);
    Ans[q[a].id]=ans;
}

}


看代码就知道 核心的算法就是

for(int a=0;a<m;a++){
        while(l<q[a].l)sub(l--);
        while(l>q[a].l)add(--l);
        while(r<q[a].r)add(++r);
        while(r>q[a].r)sub(r++);
        Ans[q[a].id]=ans;
    }
    要注意不同的题目的add 和sub函数不同,要自己写就完事了!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值