K倍区间
题目描述
思路
依照直觉来判断,这题与连续子序列的和有关,那应该先求一下前缀和 s。
那么在前缀和数列(当然这里应该已经膜过 K 了)里,如何判断 K 倍区间呢?容易得到,
[
i
,
j
]
[i,j]
[i,j] 子序列为 K 倍区间的充要条件为,
s
[
i
−
1
]
=
s
[
j
]
s[i-1]=s[j]
s[i−1]=s[j]。那么不妨统计前缀和数组中值为
k
k
k 的个数,从这些位置中任选两个,都对应着一个 K 倍区间,于是很容易就能写出下面的代码:
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int s[100005],num[100005];
int n,k;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
int _;
cin>>_;
s[i]=s[i-1]+_;
s[i]%=k;
num[s[i]]++;
}
num[0]++;
long long ans=0;
for(int i=0;i<k;i++)ans+=1LL*num[i]*(num[i]-1)/2;
cout<<ans<<endl;
return 0;
}