学习笔记——不带修序列莫队 (luogu2079)小B的询问
莫队是一种对于询问的离线算法
时间复杂度:O(\(n \sqrt n\))
大致思想就是
首先将询问离线,然后对原序列分块,使得每一个\(l和r\)都在一个块里
然后按照左节点排序,若所在的块相等,就比较右节点
int cmp1(Node a,Node b)
{
if (pos[a.l]==pos[b.l]) return a.r<b.r;
return a.l<b.l;
}
排序之后,我们再来分析一下时间复杂度;接下来我们会看到神奇的事情!!
刚才分析此方法的时候,我们是从L和R的偏移量分析的;我们仍然用这种方法来分析。
考虑一下在同一个块的时候。由于L的范围是确定的,所以每次L的偏移量是O(√N)
但是r的范围没有确定;r的偏移量是O(N)。
那么从一个块到另一个块呢?
明显地,r我们不需要作考虑,仍然是O(N)。
而L明显最多也是2*√N,而且这种情况下,很快就会到下下一块。所以也是O(√N)
由于有√N(根号N)个块,所以r的总偏移量是O(N*√N)
而M个询问,每个询问都可以让L偏移O(√N),所以L的总偏移量O(M*√N)
注意了,时间复杂度分析的时候一定要注意,r的偏移量和询问数目是没有直接关系的。
而L则恰恰相反;L的偏移量我们刚才也说明了,它和块的个数没有直接关系。
所以总的时间复杂度是:
O((N+M)*\(\sqrt n\))
在排序完之后,就按照顺序,一个一个求解,跳l和r
下面介绍两种操作 \(remove\)和\(insert\),分别是将这个位置移除、将这个位置加入答案
QwQ我也不知道为什么我一开始把这两个合成了一个函数
inline void update(int pos,int add)
{
ans-=poer(s[c[pos]]);
s[c[pos]]+=add;
ans+=poer(s[c[pos]]);
}
然后就是注意l和r 初始要设成 1和 0
void solve()
{
int l=1,r=0;
for (int i=1;i<=m;i++)
{
while (r<a[i].r)
{
update(r+1,1);
r++;
}
while (r>a[i].r)
{
update(r,-1);
r--;
}
while (l<a[i].l)
{
update(l,-1);
l++;
}
while (l>a[i].l)
{
update(l-1,1);
l--;
}
if (a[i].l==a[i].r)
{
a[i].ans=1;
continue;
}
a[i].ans=ans;
}
return;
}
下面引入一个经典例题:
题目大意:
小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。
对于全部的数据,1<=N、M、K<=50000
那么这道题就是一道经典的序列莫队问题了
直接上代码了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int maxn = 50010;
struct Node{
int l,r,id;
ll ans;
};
inline int read(){
int f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return x*f;
}
Node a[maxn];
int pos[maxn];
int c[maxn],n,m,block;
long long s[maxn];
int k;
ll ans;
inline ll poer(ll x){
return x*x;
}
int cmp1(Node a,Node b)
{
if (pos[a.l]==pos[b.l]) return a.r<b.r;
return a.l<b.l;
}
int cmp2(Node a,Node b)
{
return a.id<b.id;
}
inline void update(int pos,int add)
{
ans-=poer(s[c[pos]]);
s[c[pos]]+=add;
ans+=poer(s[c[pos]]);
}
void solve()
{
int l=1,r=0;
for (int i=1;i<=m;i++)
{
while (r<a[i].r)
{
update(r+1,1);
r++;
}
while (r>a[i].r)
{
update(r,-1);
r--;
}
while (l<a[i].l)
{
update(l,-1);
l++;
}
while (l>a[i].l)
{
update(l-1,1);
l--;
}
if (a[i].l==a[i].r)
{
a[i].ans=1;
continue;
}
a[i].ans=ans;
}
return;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for (int i=1;i<=n;i++)
c[i]=read();
block=(int)sqrt(n);
for (int i=1;i<=n;i++)
{
pos[i]=(i-1)/block+1;
}
for (int i=1;i<=m;i++)
{
a[i].l=read();
a[i].r=read();
a[i].id=i;
}
ans=0;
sort(a+1,a+1+m,cmp1);
solve();
sort(a+1,a+1+m,cmp2);
for (int i=1;i<=m;i++)
{
printf("%lld\n",a[i].ans);
}
return 0;
}
学习笔记——不带修序列莫队 (luogu2079)小B的询问的更多相关文章
- F. Machine Learning 带修端点莫队
F. Machine Learning time limit per test 4 seconds memory limit per test 512 megabytes input standard ...
- codeforces 940F 带修改的莫队
F. Machine Learning time limit per test 4 seconds memory limit per test 512 megabytes input standard ...
- BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=2120 标题里是两种不同的解法. 带修改的莫队和普通莫队比多了个修改操作,影响不大,但是注意一下细节 ...
- 【BZOJ】2120: 数颜色 带修改的莫队算法
[题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...
- 【bzoj4129】Haruna’s Breakfast 带修改树上莫队+分块
题目描述 给出一棵树,点有点权.支持两种操作:修改一个点的点权,查询链上mex. 输入 第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数.第二行包括n个整数a1...an,代表每个结 ...
- 【bzoj3052】[wc2013]糖果公园 带修改树上莫队
题目描述 给出一棵n个点的树,每个点有一个点权,点权范围为1~m.支持两种操作:(1)修改一个点的点权 (2)对于一条路径,求$\sum\limits_{i=1}^m\sum\limits_{j=1} ...
- P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队
\(\color{#0066ff}{ 题目描述 }\) 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支 ...
- UOJ 58 (树上带修改的莫队)
UOJ 58 糖果公园 Problem : 给一棵n个点的树,每个点上有一种颜色,对于一条路径上的点,若 i 颜色第 j 次出现对该路径权值的贡献为 w[i] * c[j], 每次询问一条路径的权值, ...
- UVA - 12345 带修改的莫队
题意显然:给出初始序列,单点修改,区间查询元素的种类. 由于时限过宽,暴力可过. 比较优秀的解法应该是莫队. 带修改的莫队题解可以看https://www.luogu.org/blog/user126 ...
随机推荐
- proto buffer
protobuf是一种高效的数据格式,平台无关.语言无关.可扩展,可用于 RPC 系统和持续数据存储系统. protobuf介绍 Protobuf是Protocol Buffer的简称,它是Googl ...
- Mybatis-plus<二>通用CRUD,分页
Mybatis-plus<二>通用CRUD,分页 与博客Mybatis-plus<一>为同一个Springboot项目. Demo GitHub下载地址:https://git ...
- elsa-core:4.ASP.NET Core Server with Elsa Dashboard
在本快速入门中,我们将了解一个最小的 ASP.NET Core 应用程序,该应用程序承载 Elsa Dashboard 组件并将其连接到 Elsa Server. ElsaDashboard + Do ...
- 从环境搭建到打包使用TypeScript
目录 1.TypeScript是什么 2.TypeScript增加了什么 3.TypeScript环境的搭建 4.TypeScript的基本类型 5.TypeScrip编译选项 6.TypeScrip ...
- Django使用tinymce富文本编辑器
1 - 安装 pip install django-tinymce==2.6.0 2 - 注册app INSTALLED_APPS = ( ... 'tinymce', ) 3 - 在setting中 ...
- CSS滤镜让图片模糊(毛玻璃效果)
CSS代码: .blur { filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */ -webkit-filter: blur(10px); ...
- FastDFS 配置 Nginx 模块及访问测试
#备注:以下nginx-1.10.3源码目录根据nginx版本号不同会有相应的变化,以nginx版本号为准#一.安装 Nginx 和 fastdfs-nginx-module1,安装 Nginx 请看 ...
- Docker安装GitLab与Runner(网关),常规设置,自动化用到k8s+token
[转]图文详解k8s自动化持续集成之GitLab CI/CD Windows里面使用Debian命令行工具完成 和Docker网络相关的命令 查看某一个容器的网络 docker inspect 容器I ...
- Python脚本运行出现语法错误:IndentationError:unexpected indent
对于py来说典型错误就是缩进,,烦不胜烦,整理一下解决方法:一个python脚本,本来都运行好好的,然后写了几行代码,而且也都确保每行都对齐了,但是运行的时候,却出现语法错误: Indentation ...
- 苹果ASA广告投放归因的接入
前段时间,苹果终于在大陆区开放了应用商店的竞价广告.毫无疑问又开启了苹果应用导量的新玩法,各大厂商都紧跟脚步吃螃蟹.本篇讲解苹果广告中的归因部分. 苹果广告其实在海外已运行多年,而因为IDFA的政策变 ...