给定一个长度为 N 的数列,A1,A2,…AN,如果其中一段连续的子序列 Ai,Ai+1,…Aj 之和是 K 的倍数,我们就称这个区间 [i,j] 是 K 倍区间。
你能求出数列中总共有多少个 K 倍区间吗?
输入格式
第一行包含两个整数 N 和 K。
以下 N 行每行包含一个整数 Ai。
输出格式
输出一个整数,代表 K 倍区间的数目。
数据范围
1≤N,K≤100000
1≤Ai≤100000
输入样例:
5 2
1
2
3
4
5
输出样例:
6
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL a[100100],cnt[100100];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]=a[i]+a[i-1];
}
LL count=0;
cnt[0]=1;
for(int i=1;i<=n;i++)
{
count=count+cnt[a[i]%k];//r前面要有余数相等才会+1,不然就是0。l,r余数相等,说明存在k倍区间.
//因为(s[r]-s[l])%k==0,即有多少个s[l]与s[r]余数相同
cnt[a[i]%k]++;
}
cout<<count;
return 0;
//cnt[0]=1;原因
//要想使得(s[l] % k ) == (s[r] % k)成立,则左端点l范围为[0 , r - 1],即还要将0%k得余数算进去,但是在循环中右端点r是从1开始的,将0忽略了,所以需要提前将cnt[0]加进去。
}