转自:https://www.cnblogs.com/tyty-Somnuspoppy/p/8454521.html
给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
输入
-----
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出
-----
输出一个整数,代表K倍区间的数目。
例如,
输入:
5 2
1
2
3
4
5
程序应该输出:
6
分析:
1、因为(sum[r] - sum[l-1]) % k == 0,可推出sum[r] % k == sum[l - 1] % k.
2、因此,将前缀和分别对K取模。
3、分别统计出取模后的各数字的个数。
#include<stdio.h> using namespace std; typedef long long LL; const int MAXN = 100000 + 10; int sum[MAXN]; int cnt[MAXN]; int main(){ int N, K; scanf("%d%d", &N, &K); for (int i = 0; i < N; ++i){ scanf("%d", &sum[i]); } sum[0] %= K; for (int i = 1; i < N; ++i){ sum[i] = ((sum[i] % K) + sum[i - 1]) % K; } LL ans = 0; for (int i = 0; i < N; ++i){ ans += cnt[sum[i]]++; } printf("%lld\n", ans + cnt[0]); return 0; }