
输入样例:
5 2 1 2 3 4 5
输出样例:
6
求解:
#include<iostream>
#define endl '\n'
using namespace std;
int main()
{
bool book[100002]; //定义一个标记数组,为了防止在前i项和为0但是本身m数组就是0而造成的无解的情况
long long m[100002];//存放前i项和相同余数 的个数
long long sum[100002];//前缀和存放前i项和
long long n,k;
cin>>n>>k;
long long a[100002];//存放输入的数组
long long cnt=0;
for (int i = 0; i < k; i++) {
m[i] = 0;
book[i] = false;
}
for(long long i=0;i<n;i++)
{
cin>>a[i];
if(i==0)//第一个sum[0]存放为a[0]
{
sum[0]=a[0];
}else{
sum[i]=a[i]+sum[i-1];//前缀和
}
m[sum[i]%k]++;//将前i项和对k同余的散列在同一个单元中
book[sum[i]%k]=true;//同时对m数组中的该位置标记为true,表示该单元存有同余的和的个数
if(sum[i]%k==0)//对第一个到第i个的和整除k的计数
{
cnt++;
}
}
for(int i=0;i<k;i++)//使用组合公式,举个例子:如果a[0]=3,说明有3个前i项和的余数是相同的,而且都是0,从这三个里边随便选两个的余数相减为0,也反映原来求余数之前这两个和的差是k的倍数
{
if(book[i]==true)
{
cnt+=m[i]*(m[i]-1)/2;//组合数公式,从n个里边选2个有(n-1)*n/2中选法
}
}
cout<<cnt;
return 0;
}
2933

被折叠的 条评论
为什么被折叠?



