莫队算法(优雅的暴力)

小B的询问

题目描述

小B 有一个长为 n n n 的整数序列 a a a,值域为 1 , k 1,k 1,k

他一共有 m m m 个询问,每个询问给定一个区间 l , r l,r l,r,求:
∑ i = 1 k c i 2 \sum\limits_{i=1}^k c_i^2 i=1∑kci2

其中 c i c_i ci 表示数字 i i i 在 l , r l,r l,r 中的出现次数。

小B请你帮助他回答询问。

输入格式

第一行三个整数 n , m , k n,m,k n,m,k。

第二行 n n n 个整数,表示 小B 的序列。

接下来的 m m m 行,每行两个整数 l , r l,r l,r。

输出格式

输出 m m m 行,每行一个整数,对应一个询问的答案。

样例 #1

样例输入 #1

复制代码
6 4 3
1 3 2 1 1 3
1 4
2 6
3 5
5 6

样例输出 #1

复制代码
6
9
5
2

提示

【数据范围】

对于 100 % 100\% 100% 的数据, 1 ≤ n , m , k ≤ 5 × 1 0 4 1\le n,m,k \le 5\times 10^4 1≤n,m,k≤5×104。

代码:

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int>PII;
const int N = 1e6 + 10;
const int MOD = 998244353;
const int INF = 0X3F3F3F3F;
const int dx[] = {-1, 1, 0, 0, -1, -1, +1, +1};
const int dy[] = {0, 0, -1, 1, -1, +1, -1, +1};
const int M = 1e9 + 7;

//莫队算法板子(优雅的暴力)

ll res;
ll pos[N];
ll a[N];
ll cnt[N];//记录出现的次数
ll ans[N];//记录答案
struct que
{
	int l, r, k;
    bool operator < (const que&w) const
	{
	    return pos[l] == pos[w.l] ? r < w.r : l < w.l;   
	};
}q[N];

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

void sub(int x)
{
	cnt[a[x]] --;
	res -= (cnt[a[x]] + 1) * (cnt[a[x]] + 1) - (cnt[a[x]]) * (cnt[a[x]]);
}
int main()
{
	int n, m, k;
	cin >> n >> m >> k;
	int siz = sqrt(n);
	for(int i = 1; i <= n; i ++) 
	{
		cin >> a[i];
		pos[i] = i / siz;
	}
	for(int i = 1; i <= m; i ++)
	{
		cin >> q[i].l >> q[i].r;
		q[i].k = i;
	}
	sort(q + 1, q + 1 + m);
	int l = 1, r = 0;
	for(int i = 1; i <= m; i ++)
	{
		while(q[i].l < l) add(-- l);
		while(q[i].r > r) add(++ r);
		while(q[i].l > l) sub(l ++);
		while(q[i].r < r) sub(r --);
		ans[q[i].k] = res;
	}
	for(int i = 1; i <= m; i ++) cout << ans[i] << endl;
	return 0;
}

莫队(发现了nmd,map得时间复杂度都是log,莫队又是暴力直接就超时了呜呜呜)

Little Elephant and Array

题面翻译

小象喜欢和数组玩。现在有一个数组 a a a,含有 n n n 个正整数,记第 i i i 个数为 a i a_i ai。

现在有 m m m 个询问,每个询问包含两个正整数 l j l_j lj 和 r j    ( 1 ⩽ l j ⩽ r j ⩽ n ) r_j \;(1\leqslant l_j\leqslant r_j\leqslant n) rj(1⩽lj⩽rj⩽n),小象想知道在 A l j A_{l_j} Alj 到 A r j A_{r_j} Arj 之中有多少个数 x x x,其出现次数也为 x x x。

输入格式

第一行 n n n 和 m m m, n n n 表示数组大小, m m m 表示询问个数;

第二行共 n n n 个数,第 i i i 个数为 a i a_i ai 的值;

接下来 m m m 行,每行两个数 l j l_j lj 和 r j r_j rj,意义如题面。

输出格式

共 m m m 行,每行一个数,表示每一次询问的答案。

样例输入 #1

复制代码
7 2
3 1 2 2 3 3 7
1 7
3 4

样例输出 #1

复制代码
3
1

代码:

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int>PII;
const int N = 1e6 + 10;
const int MOD = 998244353;
const int INF = 0X3F3F3F3F;
const int dx[] = {-1, 1, 0, 0, -1, -1, +1, +1};
const int dy[] = {0, 0, -1, 1, -1, +1, -1, +1};
const int M = 1e9 + 7;

//莫队算法板子(优雅的暴力)
//nmd map得时间复杂度
ll res;
ll pos[N];
ll a[N];
ll cnt[N];//记录出现的次数
ll ans[N];//记录答案
ll n, m;
struct que
{
	ll l, r, k;
}q[N];

bool cmp(que a, que b)
{
	return pos[a.l] == pos[b.l] ? a.r < b.r : pos[a.l] < pos[b.l];
}
void add(ll x)
{
	if(a[x] > n) return ;
	if(cnt[a[x]] == a[x]) res --;
	cnt[a[x]] ++;
	if(cnt[a[x]] == a[x]) res ++;
}

void sub(ll x)
{
	if(a[x] > n)  return ;
    if(cnt[a[x]] == a[x]) res --;
	cnt[a[x]] --;
	if(cnt[a[x]] == a[x]) res ++;
}
int main()
{
	cin >> n >> m;
	ll siz = sqrt(n);
	for(ll i = 1; i <= n; i ++) 
	{
		scanf("%lld", &a[i]);
		pos[i] = i / siz;
	}
	for(ll i = 1; i <= m; i ++)
	{
		scanf("%lld%lld", &q[i].l, &q[i].r);
		q[i].k = i;
	}
	sort(q + 1, q + 1 + m, cmp);
	ll l = 1, r = 0; 
	for(ll i = 1; i <= m; i ++)
	{
		while(q[i].l < l) add(-- l);
		while(q[i].r > r) add(++ r);
		while(q[i].l > l) sub(l ++);
		while(q[i].r < r) sub(r --);
		ans[q[i].k] = res;
	}
	for(ll i = 1; i <= m; i ++) cout << ans[i] << '\n';
	return 0;
}
相关推荐
布莱克60511 分钟前
C++中的内存分区详解
c++
All for pursuit.37 分钟前
【链表-9】146.LRU缓存
数据结构·c++·算法·leetcode
木子算法38 分钟前
测出来的值会抖:约束和目标带噪声时,「可行」和「更好」该怎么判
人工智能·算法·目标跟踪
j7~2 小时前
【C++微服务项目开发脚手架】(接口篇一)gflags + gtest + spdlog 接口学习笔记
c++·学习·gtest·项目开发·spdlog·gflags·c++项目微服务开发脚手架
hanlin032 小时前
刷题笔记:力扣第144题-二叉树的前序遍历
笔记·算法·leetcode
金士曼2 小时前
从规则到涌现:算法认知的三个层次
算法
星期八不上发条2 小时前
智能指针是什么?使用场景,循环引用解决办法,面试回答
开发语言·c++·stl
ao-weilai2 小时前
Linux网络编程:Socket UDP
linux·服务器·网络·c++
彧azz2 小时前
图的最短路径:Dijkstra与Floyd算法
数据结构·笔记·学习
智购科技自动售卖机厂家2 小时前
设备一到夏天就频繁跳闸,从启动电流追到压缩机电容~YH
数据结构·人工智能·python·eclipse