分析:对于数据范围来说,本题不能用O(n^2)来做,
当求完前缀和之后,在1~r 区间中,很容易想到我们只需要找出满足( (sum[r]-sum[l-1])%k == 0 )的个数(这个式子可以变为sum[r]%k==sum[l-1]%k),但因为是l-1,不太容易求,那么当把变为sum[l]时,范围就变为了0~r-1 。
我们可以每次从前往后枚举,枚举到第 i 位 ,如果前面有一位 j 满足 (sum[i]-sum[j])==0 ,表示aj+1,,,ai之间的和是k的倍数,因为我们可能遇到j为0的情况,也就是1~i是k的倍数,所以我们需要预处理一下cnt[0]=1;
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
int a[N];
int res[N];
int n,k;
int main()
{
cin>>n>>k;
LL ans=0;
int cnt=0;
res[0]=1;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]=(a[i-1]+a[i])%k;
ans+=res[a[i]];
res[a[i]]++;
}
cout<<ans<<endl;
return 0;
}