算法1
思路:前缀和
一般像这种求前多少项和,前多少项和是什么的倍数,第一个要想到前缀和,还有需要注意的一点,一般说是多少的倍数,因为取值会比较大,就需要取模运算,怎样判别是一类呢?那就是取模之后相等。
所以像这个题,就可以理解为%k==0的有多少个组合,sum[i]%k==0,都是满足要求的,接下来统计相同sum[i]%k==0的个数,比如sum[r]-sum[l-1]之间的数%k==0,用res存同样的sum[i]的个数值,用ans一直叠加sum[i]%k相同的个数,后面再加上%k==0,也就是res[0]的个数
C++ 代码
#include<iostream>
using namespace std;
const int N=100010;
typedef long long LL;
int sum[N],a[N],res[N];
int n,k;
LL ans=0;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=(sum[i-1]+a[i])%k;//前缀和取模
ans+=res[sum[i]];
res[sum[i]]++;//两个相等前缀和就能组成一个K倍区间
}
cout<<ans+res[0]<<endl;
return 0;
}