首页 > 其他分享 >[莫队]

[莫队]

时间:2024-02-29 16:16:33浏览次数:20  
标签:cnt sub int res belong maxn 莫队

P2709

莫队

特点

是一种优雅的暴力

解决大部分区间离线问题的离线算法

主要思想为分块,将 \(n^2\) 降为 \(n \sqrt{n}\)

题目关键词包含\(n,m,k\),并有多个询问\(L_i,R_i\),求区间内的...

思想

相当于有两个指针\(L,R\),若当前询问的区间为\(l[i],r[i]\)那么会分别将 \(L,R\) 向\(l[i],r[i]\)的方向移动,并在移动时做出与题目要求相关的操作

模板

int sz = sqrt(n);//每一块的大小为根号n
for(int i=1;i<=n;i++)
  belong[i] = i / sz; //将每一个位置划分到对应的块里面去
sort();//先按照每次询问的左端点所在的块号排序,如果两个区间左端点所在的块相同,那么按照右端点小的在前
int L = 1,R = 0;//初始化两个指针,R = 0,是为了能将第一个添加进去
for(int i=1;i<=m;i++)
{
	while(q[i].l < L) add(--L);
	while(q[i].l > L) sub(L++);
	while(q[i].r < R) sub(R--);
	while(q[i].r > R) add(++R);
	ans[q[i].id] = res;//q[i].id表示原来它是第几次询问,因为要跟询问顺序保持一致,res为每次更新区间之后的答案
}

P2709 code

#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;
const int maxn = 5e4+5;
int n,m,k,a[maxn],belong[maxn],cnt[maxn];
LL res,ans[maxn];
struct range{
	int l,r,id;
}q[maxn];

bool cmp(range x,range y)
{
	return belong[x.l] == belong[y.l] ? x.r < y.r : belong[x.l] < belong[y.l];
}

void add(int x)
{
	res = res + 2 * cnt[a[x]] + 1;
	cnt[a[x]] ++;
	return ;
}

void sub(int x)
{
	res = res - 2 * cnt[a[x]] + 1;
	cnt[a[x]] --;
	return ;
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	int sz = sqrt(n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		belong[i] = i / sz;
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&q[i].l,&q[i].r);
		q[i].id = i;
	}
	sort(q+1,q+m+1,cmp);
	int L = 1,R = 0;
	for(int i=1;i<=m;i++)
	{
		while(q[i].l < L) add(--L);
		while(q[i].l > L) sub(L++);
		while(q[i].r < R) sub(R--);
		while(q[i].r > R) add(++R);
		ans[q[i].id] = res;
	}
	for(int i=1;i<=m;i++)
		printf("%lld\n",ans[i]);
	return 0;
} 

标签:cnt,sub,int,res,belong,maxn,莫队
From: https://www.cnblogs.com/-Wind-/p/18044423

相关文章

  • 分块和莫队
    1分块1.1概念简述分块被称为“优雅的暴力”。对于一个区间$[1,n]$,我们将其分成若干个块。在处理整块时直接维护整块信息,达到降低时间复杂度的目的。对于常规分块,设块长为$m$,则一般情况下$m$取$\sqrt{n}$时复杂度最优。下面举几例来说明分块如何降低时间复杂度。1.2......
  • 根号分治与莫队算法
    1.根号分治与分块在预处理与询问的复杂度之间寻找平衡的一个算法,通常以根号为分界线。属于智慧的暴力。1.1.根号平衡使用数学不等式对于阈值取一个值,使得复杂度最优。如果有阈值\(B\),若问题有一部分暴力可以\(O(B)\)解决,另一部分可以\(O(\frac{n}{B})\)解决。那么根据基......
  • 莫队算法学习笔记
    普通莫队形式¶假设\(n=m\),那么对于序列上的区间询问问题,如果从\([l,r]\)的答案能够\(O(1)\)扩展到\([l-1,r]\)\([l+1,r]\)\([l,r-1]\)\([l,r+1]\)(即与\([l,r]\)相邻的区间)的答案,那么可以在\(O(n\sqrt{n})\)的复杂度内求出所有询问的答案。实现¶离线后排序,顺序处理......
  • 莫队与分块
    【根号分治】例题:等差数列加给定一个长度\(n\)的数列,初始全都是0。(\(n\leq2\times10^5\))要求支持两种操作:\(1\;x\;y\;d\),表示把所有下标模\(x\)等于\(y\)的位置全部加上\(d\);\(2\;x\),表示查询\(a_x\)当前值。做法:对于所有\(x>\sqrtn\),我们直接暴力循环......
  • 『学习笔记』莫队
    Part0.目录概念普通莫队树上莫队带修莫队Part1.概念莫队是由莫涛提出的算法。莫队算法可以解决一类离线区间询问问题,适用性极为广泛。Part2.普通莫队普通莫队主要针对于多次区间询问的问题,基于分块的思想。过程如下:先将当前区间\([l,r]\)设为\([1,0]\),再每次......
  • 莫队
    莫队介绍莫队算法可以解决一类离线区间询问问题,适用性极为广泛。同时将其加以扩展,便能轻松处理树上路径询问以及支持修改操作。普通莫队算法形式假设\(n=m\),那么对于序列上的区间询问问题,如果从\(\left[l,r\right]\)的答案能够\(O(1)\)扩展到\(\left[l,r+1\right],\lef......
  • 莫队学习笔记
    莫队莫队是一种常见的离线处理区间查询问的方法。莫队的思想是把序列分块,然后把询问按照左端点所在块为第一关键字,右端点为第二关键字排序,然后处理询问,维护指针\(l,r\)表示当前处理的区间是\([l,r]\),每次根据询问区间来移动指针计算贡献。关于复杂度。假设指针移动的复杂度......
  • 莫队
    莫队莫队的运用非常广泛,今天我们就主要收录莫队的常见运用,以及一些思维和实践上的小技巧。基础莫队众所周知莫队是一种离线算法,而这里的基础莫队,指的是多关键字的莫队。基础莫队要求支持计算单个元素变化的贡献,并且与元素贡献的顺序无关。当我们的询问有多个关键字时,我们可以......
  • 分块与莫队算法
    1.分块分块的思想分块是把一个长度为\(N\)的数列分为\(\sqrt{N}\)个块,每个块的长度为\(\sqrt{N}\)。这样在区间操作的时候,对于每个涉及到的块,如果涉及到半个块,就直接操作;如果涉及到整个块,就整体操作。下面通过例题来了解一下分块。例1洛谷-P3372这道题可以用分块来做......
  • 莫队算法
    简要介绍:莫队算法是先进行分块,然后按照分块来排序,然后对已知区间进行增减以达到所求区间,记录下答案,最后按照所询问的顺序进行输出答案。如对于已知区间[l,r]要求[l-1,r],[l-2,r],[l-3,r],[l-4,r],则将已知区间向左移,同时进行add添加操作;而对于要求[l,r+1],[l,r+2],[l,r+3],[l,r+......