列表

详情


NC14690. 序列

描述

na1,a2,,anK
q
一个二元组(l, r), 其中1lr n,
所有满足以下条件的二元组(l2, r2)的数目:
1: 1ll2r2rn,
2: 是k的倍数。

输入描述

第一行一个整数T,表示有T组数据。
对于每组数据,
第一行输入3个整数, n, q, k,
接下来一行输入n个整数,a1,a2,…,an
接下来q行,每行输入2个整数 l, r

输出描述

对于每一个询问,输出满足条件的二元组(l2,r2)的数目。

示例1

输入:

1
5 2 4
4 1 4 8 8
2 2 
2 4

输出:

0
3

说明:

当(l, r)为(2, 4)时,
(l2,r2)=(3,4),a3+a4=12,是4的倍数
(l2,r2)=(3,3),a3=4,是4的倍数
(l2,r2)=(4,4),a4=8,是4的倍数

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 602ms, 内存消耗: 3120K, 提交时间: 2022-04-19 13:21:43

#include <bits/stdc++.h>

#define ll long long
#define N 100010

using namespace std;

int T, n, q, k;
ll sum, s[N], ans[N];

struct Q { int l, r, i; } qu[N];
unordered_map <int, int> cnt;

inline void add(int p) { sum += cnt[s[p]]++; }
inline void del(int p) { sum -= --cnt[s[p]]; }

int main() {
	scanf("%d", &T);
	while (T--) {
		scanf("%d %d %d", &n, &q, &k);
		for (int i = 1; i <= n; ++i) {
			scanf("%lld", s + i);
			(s[i] += s[i - 1]) %= k;
		}
		for (int i = 1; i <= q; ++i)
			scanf("%d %d", &qu[i].l, &qu[i].r), qu[i].i = i;
		int len = sqrt(n);
		sort(qu + 1, qu + q + 1, [len](const Q& a, const Q& b) {
			return (a.l / len ^ b.l / len) ? a.l < b.l : a.r < b.r;
		});
		cnt.clear(), sum = 0;
		int L = 1, R = 0;
		for (int i = 1; i <= q; ++i) {
			while (R < qu[i].r) add(++R);
			while (R > qu[i].r) del(R--);
			while (L > qu[i].l) add(--L);
			while (L < qu[i].l) del(L++);
			ans[qu[i].i] = sum + cnt[s[qu[i].l - 1]];
		}
		for (int i = 1; i <= q; ++i) printf("%lld\n", ans[i]);
	}

	return 0;
}

上一题