普通莫队概念

莫队:莫涛队长发明的算法,尊称莫队。其实就是优化的暴力。

普通莫队只兹磁询问不支持修改,是离线的。

莫队的基本思想:就是假定我得到了一个询问区间[l,r]的答案,那么我可以在极短(通常是O(1))的时间复杂度内得到[l+1,r]的答案——于是对于区间查询类的题目,我可以一次性读完所有询问之后来回转移,得到每一个区间的答案。

如果可以通过区间[l,r]快速转移到[l-1,r][l+1,r][l,r-1][l,r+1],那么可以用O(x*|l1-l2|+|r1-r2|)的时间完成转移,[l2,r2]是[l1,r1]的后一次询问,x是[l,r]转到相邻区间的复杂度,我们让这个值最小,就是求曼哈顿距离最小生成树,但是这个比较难求。可以用分块加上一定规则来排序,以左端点所在块的编号为第一关键字排序,右端点的值作为第二关键字排序,最坏复杂度和上面的曼哈顿距离最小生成树是一样的,这个样子做的复杂度是 $O(n \sqrt n) $(不会证,反正使用分块后复杂度就是这)。

在这里,分块的作用就是加速而已。

题目

小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数

分析:

无修改莫队模板题,用一个数组记录当前区间每种数字出现的次数,在莫队转移是进行维护。

先读入所有的查询并排序,然后完成指针跳转得到每次查询的结果,最后根据查询顺序排序并输出结果。

对查询排序有两种方法:

  • 左端点所在块的编号为第一关键字排序,右端点的值作为第二关键字排序
  • 左端点所在块的编号为第一关键字排序,块号相同时,如果块序号为奇就升序排r,否则降序
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int maxn = + ;
struct Que{
int l, r, id; //id表示是第几次询问
ll res; //当前询问的答案
}q[maxn]; int n, m, k;
ll block[maxn], num[maxn], sum[maxn], size;
ll ans;
//block: 分块数组 size分块大小
//sum[i]: 元素i的个数 void init()
{
size = (int)sqrt(n);
for(int i = ;i <= n;i++) block[i] = (i-) / size + ;
} //莫队精髓一
bool cmp(Que x, Que y)
{
return block[x.l] == block[y.l] ? x.r < y.r : x.l < y.l;
} bool cmpp(Que x, Que y)//第二种排序方式,快一些
{
return (block[x.l] ^ block[y.l]) ? block[x.l] < block[y.l] : ((block[x.l] & ) ? x.r < y.r : x.r > y.r);
} //按查询顺序排序,用于输出答案
bool cmp_id(Que x, Que y)
{
return x.id < y.id;
} //莫队精髓二:转移
void modify(int x, int w)
{
ans -= sum[num[x]] * sum[num[x]]; ///先将这个位置数的原来sum的平方减去
sum[num[x]] += w; //更新个数统计数组
ans += sum[num[x]] * sum[num[x]]; //然后加上新的sum
} void solve()
{
int l = , r = ; //莫队精髓三:两个小指针来回跳,表示当前ans维护的区间的左右端点
for(int i = ;i <= m;i++)
{
while(r < q[i].r) modify(r+, ), r++;
while(r > q[i].r) modify(r, -), r--;
while(l < q[i].l) modify(l, -), l++;
while(l > q[i].l) modify(l-, ), l--;
q[i].res = ans;
}
} int main()
{
scanf("%d%d%d", &n, &m, &k);
for(int i = ;i <= n;i++) scanf("%lld", &num[i]);
for(int i = ;i <= m;i++)
{
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id = i;
} init();
sort(q+, q+m+, cmp); //or cmpp solve(); sort(q+, q+m+, cmp_id);
for(int i = ;i <= m;i++)
printf("%lld\n", q[i].res); return ;
}

参考链接:

1. https://www.luogu.org/problemnew/solution/P2709?page=2

2. https://www.luogu.org/problemnew/solution/P1494

P2709 小B的询问——普通莫队&&模板的更多相关文章

  1. P2709 小B的询问(莫队)

    P2709 小B的询问 莫队模板 资磁离线询问 维护两个跳来跳去的指针 先分块,蓝后询问按块排序. 蓝后每次指针左右横跳更新答案 #include<iostream> #include&l ...

  2. 【Luogu P2709 小B的询问】莫队

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  3. P2709 小B的询问(莫队入门)

    题目链接:https://www.luogu.org/problemnew/show/P2709 题目大意:中文题目 具体思路:莫队入门题,按照离线的方式打的,对每一个区间进行分块和编号,如果在同一个 ...

  4. 洛谷 P2709 小B的询问(莫队)

    题目链接:https://www.luogu.com.cn/problem/P2709 这道题是模板莫队,然后$i$在$[l,r]$区间内的个数就是$vis[ ]$数组 $add()$和$del()$ ...

  5. 【Luogu】P2709小B的询问(莫队算法)

    题目链接 md,1A率等于0. 烦死. 终于搞到一道莫队了qwq. 先对区间分块再按照块编号为第一关键字,右端点为第二关键字排序,然后每次端点移动1乱搞. 然后……就wa了. 然后有很多细节需要注意q ...

  6. 【洛谷2709】小B的询问(莫队模板题)

    点此看题面 大致题意: 有一个长度为\(N\)的序列,每个数字在\(1\sim K\)之间,有\(M\)个询问,每个询问给你一个区间,让你求出\(\sum_{i=1}^K c(i)^2\),其中\(c ...

  7. P2709 小B的询问 (莫队板子)

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  8. BZOJ_3781_小B的询问_莫队

    BZOJ_3781_小B的询问_莫队 Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值 ...

  9. 小B的询问(题解)(莫队)

    小B的询问(题解)(莫队) Junlier良心莫队 题目 luoguP2709 小B的询问 code #include<bits/stdc++.h> #define lst long lo ...

随机推荐

  1. [Agc029A]Irreversible operation_逆序对

    Irreversible operation 题目链接:https://atcoder.jp/contests/agc029/tasks/agc029_a 数据范围:略. 题解: 假设黑色是$1$,白 ...

  2. mysql数据库基础-2019-9-10(随堂笔记)

    mysql数据库基础 在cmd情况下启动mysql数据库:(配置path环境变量后可忽略) 运行mysql1. 进入mysql路径2. 执行:mysql -uroot -p,安装时的密码 1.数据库& ...

  3. PL/SQL developer 11.0注册码

    PL/SQL developer 11.0注册码:product key:lhsw85g33x4p7leqk63hy8q28ffxzzvbxlserial No:193085password:xs37 ...

  4. 【第一季】CH06_FPGA设计Verilog基础(三)

    [第一季]CH06_FPGA设计Verilog基础(三) 一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的.学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情. ...

  5. FGL内置函数大全

    内置功能摘要: 内置的功能是什么?内置的功能列表支持的功能列表键代码表另请参阅:效用函数,变量,函数,操作符,内置类. ---------------------------------------- ...

  6. 【AC自动机】Keywords Search

    [题目链接] https://loj.ac/problem/10057 [题意] 原题来自:HDU 2222 给定  n 个长度不超过 50 的由小写英文字母组成的单词准备查询,以及一篇长为 m 的文 ...

  7. docker-registry的定制和性能分析

    docker-index Web UI Meta-data 元数据存储(附注.星级.公共库清单) 访问认证 token管理 存储镜像.以及镜像层的家族谱系 没有用户账户数据 不知道用户的账户和安全性 ...

  8. 利用element-ui封装地址输入的组件

    我们前端做项目时,难免会遇到地址输入,多数情况下,我们都是提供一个省市三级联动,加上具体地址输入的Input输入框给用户,用以获取用户需要输入的真实地址.在需要对用户输入的数据进行校验的时候,我们会单 ...

  9. hdu 1281 匈牙利算法

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  10. C#Random随机值重复的解决方法

    使用如上图所示的代码,将会出现如下情况,明明是随机,可值都是同样的,这样的随机几率也太小了,所以估计是代码有问题. 于是搜索了下,发现引起这个问题的原因是C#中的Random是根据时间来产生随机数,而 ...