Luogu P2709 小B的询问

https://www.luogu.com.cn/problem/P2709#submit

小B的询问

题目描述

小B 有一个长为 n 的整数序列 a,值域为 [1,k]
他一共有 m 个询问,每个询问给定一个区间 [l,r],求:

i=1kci2

其中 ci 表示数字 i[l,r] 中的出现次数。
小B请你帮助他回答询问。

输入格式

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

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

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

输出格式

输出 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% 的数据,1n,m,k5×104

//标准莫队板子
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n, m, k, block;
int l = 1, r = 0, out[5211314], ans;
int a[5211314], pos[5211314], cnt[5211314];
struct ASK {
int l, r, id;
}ask[5211314];
inline bool cmp(ASK a, ASK b) {
if (pos[a.l] != pos[b.l]) return pos[a.l] < pos[b.l];
else return a.r < b.r;
}
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch - '0');
ch = getchar();
}
return x * f;
}
inline void Add(int x) {
ans = ans + 2 * cnt[x] * 1 + 1;
cnt[x] ++;
return;
}
inline void Del(int x) {
ans = ans - 2 * cnt[x] * 1 + 1;
cnt[x] --;
return;
}
int main() {
n = read();
m = read();
k = read();
block = sqrt(n);
for (int i = 1; i <= n; ++ i) {
a[i] = read();
pos[i] = (i - 1) / block + 1;
}
for (int i = 1; i <= m; ++ i) {
ask[i].l = read();
ask[i].r = read();
ask[i].id = i;
}
sort(ask + 1, ask + 1 + m, cmp);
for (int i = 1; i <= m; ++ i) {
while (ask[i].l < l) Add(a[-- l]);
while (l < ask[i].l) Del(a[l ++]);
while (r < ask[i].r) Add(a[++ r]);
while (ask[i].r < r) Del(a[r --]);
out[ask[i].id] = ans;
}
for (int i = 1; i <= m; ++ i) {
printf("%d\n", out[i]);
}
return 0;
}
posted @   觉清风  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示