# 莫队算法小结(待更新)

目录

  • 莫队算法小结(待更新)

    • 简单介绍
    • 基础莫队
    • 带修莫队
    • 树上莫队

莫队算法小结(待更新)

简单介绍

博客安利:

  1. OI Wiki
  2. 大米饼

解决一类离线区间查询问题,分块思想,时间复杂度\(O(n\sqrt n)\)

  • 排序

    读入的时候对整个数组进行分块,块大小一般使用\(\sqrt n\),对询问操作排序的时候,先以块号为第一关键字,\(r\)为第二关键字,从小到大排序,然后逐个遍历

    离线后将询问排序,顺序处理每个询问,暴力从上一个区间的答案转移到下一个区间的答案(通过两个指针的\(++\)和\(--\)操作实现)

  • 指针移动

    当\(l\)指针从绿色区域向右移动一格,更新操作对应,先减去cnt[绿色]的共享,cnt[绿色]\(--\),再加上cnt[绿色]区域的贡献,其他指针移动操作类似。

基础莫队

  • 题目链接:

    给出n只袜子颜色,每次给个区间\([l,r]\),询问这个区间连续取两只袜子取到同一种颜色的概率。

  • 思路:

    对于L,R的询问。

    设其中颜色为x,y,z的袜子的个数为a,b,c..…

    那么答案即为 \((a*(a-1)/2+b*(b-1)/2+c*(c-1)/2....)/((R-L+1)*(R-L)/2)\)

    化简得: \((a^2+b^2+c^2+...x^2-(a+b+c+d+.....))/((R-L+1)*(R-L))\)

    即: \((a^2+b^2+c^2+...x^2-(R-L+1))/((R-L+1)*(R-L))\)

    我们需要解决的一个问题是:求一个区间内每种颜色数目的平方和。

  • AcCode:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=5e4+5;
//存储询问区间
struct node{int l,r,id;LL A,B;}q[maxn];
//in[]存储每个数所在的区间
int n,m,a[maxn],in[maxn];
//处理前预排序
inline bool cmp(node& a,node& b){
    return in[a.l]==in[b.l]?a.r<b.r:a.l<b.l;
}
//处理完,返回原来询问的顺序
inline bool CMP(node& a,node& b){return a.id<b.id;}
//cnt[]存储每个数的个数
int ans,cnt[maxn];
LL pow(LL x){return x*x;}
inline void update(int x,int d){
    ans-=pow(cnt[a[x]]),cnt[a[x]]+=d,ans+=pow(cnt[a[x]]);
}
inline void solve(){
    int l=1,r=0;
    for(int i=1;i<=m;++i){
        while(l<q[i].l)update(l,-1),l++;
        while(l>q[i].l)update(l-1,1),l--;
        while(r<q[i].r)update(r+1,1),r++;
        while(r>q[i].r)update(r,-1),r--;

        if(l==r){q[i].A=0,q[i].B=1;continue;}
        q[i].A=ans-(r-l+1);
        q[i].B=1LL*(r-l+1)*(r-l);
        LL gc=__gcd(q[i].A,q[i].B);
        q[i].A/=gc,q[i].B/=gc;
    }
}
int main(){
    cin>>n>>m;
    int sqr=sqrt(n);
    for(int i=1;i<=n;++i)cin>>a[i],in[i]=i/sqr+1;
    for(int i=1;i<=m;++i)cin>>q[i].l>>q[i].r,q[i].id=i;

    sort(q+1,q+1+m,cmp);

    solve();

    sort(q+1,q+1+m,CMP);

    for(int i=1;i<=m;++i)
        printf("%lld/%lld\n",q[i].A,q[i].B);
    return 0;
}

带修莫队

树上莫队

原文地址:https://www.cnblogs.com/sstealer/p/11703307.html

时间: 2024-10-12 06:47:50

# 莫队算法小结(待更新)的相关文章

莫队算法小结(Markdown版)

wtf,最近挖坑有点小多啊,没办法>_<容我先把糖果公园A了再来写这个吧= =看看今天能不能A掉 好吧,我承认我第二天才把糖果公园A掉>_<下面把这篇小结补上 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m个询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为0则输出01 仔细观察发现,令x表示x这个值出现的次

莫队算法小结

唔,想有更加舒爽的阅读体验请移步http://mlz000.logdown.com/posts/252433-mo-algorithm-summary 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为则输出0/1 仔细观察发现,令x表示x个值出现的次数,则每次询问[l,r]区

莫队算法小结以及模板题

被splay折磨了一个星期还是抄模板都wa,调试的时候查数据都发现数据太大不能查的蒟蒻杨澜决定学习莫队算法, 但是 万万没想到 莫队也到处都是坑 ----------------------------------------------题记 莫队这个东西就是一个非常简♂单的类似动规的东西,也是那种不会就一直不会,一看题解秒懂的题,[虽然我看题解也半天看不懂但是只是第一道题,万事开头难嘛(也许吧)] 莫队算法是一种基于分块的离线算法,主要用来解决一些区间的询问[就是暴力],我们需要做的就是把询问

【BZOJ3781、2038】莫队算法2水题

[BZOJ3781]小B的询问 题意:有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数 题解:初学莫队算法,差不多明白了用莫队的情况,对于这种离线的,区间长度+1时可O(1)修改答案的题,运用莫队算法是最水的 将n分成sqrt(n)块,将询问按照左端点所在的块为第一关键字,右端点的具体位置为第二关键字排序,然后用指针l,r不断暴力平移到询问的左右端点处,

B 洛谷 P3604 美好的每一天 [莫队算法]

题目背景 时间限制3s,空间限制162MB 素晴らしき日々 我们的情人,不过是随便借个名字,用幻想吹出来的肥皂泡,把信拿去吧,你可以使假戏成真.我本来是无病呻吟,漫无目的的吐露爱情---现在这些漂泊不定的鸟儿有地方栖息了,你可以从信里看出来.拿去吧---由于不是出自真心,话就说得格外动听,拿去吧,就这么办吧... 由于世界会在7月20日完结,作为救世主,间宫卓司要在19日让所有人回归天空 现在已经是19日傍晚,大家集合在C栋的天台上,一共n个人 在他们面前,便是终之空,那终结的天空 题目描述 回

[hdu5213]容斥原理+莫队算法

题意:给一个序列a,以及K,有Q个询问,每个询问四个数,L,R,U,V, 求L<=i<=R,U<=j<=V,a[i]+a[j]=K的(i, j)对数(题目保证了L <= R < U <= V). 思路:首先用容斥原理把询问变为i,j同区间,记f(A,B)为答案,'+'为区间的并,A=[L,R],B=[U,V],C=[u+1,v-1],则f(A,B) = f(A+B+C,A+B+C)+f(C,C)-f(A+C,A+C)-f(B+C,B+C).令g(L,R) = f(

[voj 1551]E - Pairs 2014年武汉大学邀请赛E题 莫队算法

题目大意 有n个数,m个查询,对于每个查询,询问指定区间,有多少个数对的绝对值小于等于2. 解题思路 莫队O^1.5 首先将询问离线处理左端点进行编号,每sqrt(n)个为一组 sort结构体 当左端点编号相同时,比较右端点大小.小的放在前面. 对于每组询问暴力处理,只需处理当前新加入(删除的数字在当前区间内有多少点和它的绝对值只差小于2即可) 唯一要注意的是加点是先更新答案再计数,删点是先计数器-1再更新答案 因为对于每个询问,左端点的修改量不超过sqrt(n) 右端点每一组最坏的复杂度是修改

XOR and Favorite Number(莫队算法+分块)

E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pai

带修改的莫队算法学习小记

简介 莫涛大神创造出的离线询问算法的带修改版. 算法基础:需要掌握莫队算法,会打暴搜(暴力). 一个叫莫的双端队列. 只支持单点修改 操作方法 普通的不带修改的莫队算法要把每个询问带上两个关键字排序,现在待修改的莫队算法要带上三个关键字排序. 初始操作 fo(i,1,m) { scanf("%s%d%d",s,&k,&l); if (s[0]=='Q')a[++tot].l=k,a[tot].r=l,a[tot].x=num,a[tot].p=tot; else d[+