首页 > 编程语言 >莫队算法

莫队算法

时间:2024-08-27 17:15:18浏览次数:7  
标签:cnt int pos 1000001 -- 算法 now 莫队

特点:

快速、离线处理(支持查询,不支持修改)、暴力处理长序列问题

核心思想:

  • 双指针的移动
  • 分块和排序

示例题洛谷P1972 [SDOI2009] HH的项链
ps:实际这道题用莫队会被卡,仅用于举例

#include<bits/stdc++.h>
using namespace std;

struct q
{
    int l;
    int r;
    int id;
}ql[1000001];
int n,m;int a[1000001];int ans[1000001];int belong[1000001];int cnt[1000001];int now;int res[1000001];
int cmp(q a,q b)
{
    //return belong[a.l]==belong[b.l]?a.r<b.r:belong[a.l]<belong[b.l];
    return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r);
}
void add(int pos)
{
    if(cnt[a[pos]]==0)++now;
    ++cnt[a[pos]];
}
void del(int pos)
{
    --cnt[a[pos]];
    if(cnt[a[pos]]==0)--now;
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>ql[i].l>>ql[i].r;
        ql[i].id=i;
    }
    int size=sqrt(n);
    int bnum=ceil(double(n)/size);
    for(int i=1;i<=bnum;i++)
        for(int j=(i-1)*size+1;j<=i*size;j++)
            belong[j]=i;
    sort(ql+1,ql+m+1,cmp);
    int l=1,r=0;
    for(int i=1;i<=m;i++)
    {
        int nl=ql[i].l;int nr=ql[i].r;
        //cout<<ql[i].l<<" "<<ql[i].r<<endl;
        //cout<<"l: "<<l<<" r: "<<r<<endl;
        while(l<nl)del(l++);
        while(l>nl)add(--l);
        while(r>nr)del(r--);
        while(r<nr)add(++r);
        res[ql[i].id]=now;
    }
    for(int i=1;i<=m;i++)
        cout<<res[i]<<endl;
    return 0;
}

实际上使用cnt数组存中间结果用的是1-1哈希映射,大概率空间浪费会挺大,而且某些数据集也不支持这种做法。

一些优化

while(l < ql) now -= !--cnt[aa[l++]];
while(l > ql) now += !cnt[aa[--l]]++;
while(r < qr) now += !cnt[aa[++r]]++;
while(r > qr) now -= !--cnt[aa[r--]];

标签:cnt,int,pos,1000001,--,算法,now,莫队
From: https://www.cnblogs.com/Arc-ux/p/18383160

相关文章

  • C++学习随笔——算法transform和lambda的用法
    std::transform是一个常用的STL算法,用于对序列中的每个元素进行操作,并将结果存储在另一个序列中。lambda表达式是一种匿名函数,可以在需要传递函数作为参数的场景中使用,比如在std::transform中。语法://一元操作std::transform(InputIterator1first1,InputIterator1la......
  • 【图像分割】复合粒子群算法CPSOGSA图像多级阈值分割【含Matlab源码 7349期】
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信或扫描文章底部QQ二维码。......
  • 算法与数据结构——哈希表
    哈希表哈希表(hashtable),又称散列表,它通过建立键key与值value之间的映射,实现高效的元素查询。具体而言,我们向哈希表中输入一个键key,则可以在O(1)时间内获取对应的值value。除哈希表外,数组和链表也可以实现查询功能,他们的效率对比如下表:添加元素:仅需将元素添加至数组(链表)的尾部......
  • 逻辑回归算法 0基础小白也能懂
    逻辑回归算法0基础小白也能懂(附代码)原文链接啥是逻辑回归算法逻辑回归(LogisticRegression)是一种广泛用于分类任务的统计模型,特别适用于二元分类问题。尽管名称中带有“回归”,但逻辑回归主要用于分类。逻辑回归算法包含以下几个关键部分:线性回归与分类,Sigmoid函数与决策边......
  • 「代码随想录算法训练营」第四十八天 | 图论 part6
    目录108.冗余连接109.冗余连接II108.冗余连接题目链接:https://kamacoder.com/problempage.php?pid=1181文章讲解:https://www.programmercarl.com/kamacoder/0108.冗余连接.html题目状态:看题解思路:构建并查集,然后通过并查集来判断节点,若当前这对节点(s,t)在同一个集合......
  • 超棒!适合毕业论文!很全面!基于蚁群算法的路径规划研究(包含GUI)(Matlab代码实现)
      ......
  • mitk滤波算法有哪些以及应用场景
    一.mitk滤波算法有哪些MITK(MedicalImagingInteractionToolkit)提供了多种滤波算法用于医学图像处理。以下是一些常见的MITK滤波算法及其简要说明:1.高斯滤波(GaussianFilter)  -用途:平滑图像,减少噪声  -原理:使用高斯函数作为卷积核2.中值滤波(Median......
  • 二分查找算法:朴素二分+左右边界二分&力扣实战应用
    目录:1、二分查找算法简介2、算法原理及时间复杂度分析2.1朴素二分算法3.2查找左右边界的二分算法3.2.1查找左边界3.2.2查找右边界3.3时间复杂度分析3、二分查找算法模版3.1朴素二分模版3.2查找左右边界的二分模版4、算法应用【leetcode】4.1题一:搜素插入位......
  • MATLAB智能优化算法-学习笔记(1)——遗传算法求解0-1背包问题【过程+代码】
    一、问题描述(1)数学模型(2)模型总结目标函数:最大化背包中的总价值Z。约束条件:确保背包中的物品总重量不超过容量W。决策变量:每个物品是否放入背包,用0或1表示。这个数学模型是一个典型的0-1整数线性规划问题。由于其NP完全性,当问题规模较大时,求解此问题通常需要使用启发......
  • 【JUC并发编程系列】深入理解Java并发机制:CAS算法与原子类在Java中的实践应用(二、CAS
    文章目录【JUC并发编程系列】深入理解Java并发机制:CAS算法与原子类在Java中的实践应用(二、CAS)1.同步之原子类(Atomic类)2.使用atomicInteger计数3.使用atomicInteger底层原理3.compareAndSet原理分析3.1手写AtomicInteger3.2手写Lock锁3.3CASaba的问题3.4Atomic......