解题思路:区间
[L,R]
的和为K的倍数可以推出
[1,2...L−1]
%K==
[1,2....R]
%K。于是可以预处理出所有的前缀和对K取模的得到的余数,对每一个余数存在的个数n取
C2n
将和加起来即可,注意答案可能超出int。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;
const int Max=1e5+100;
int data[Max], cnt[Max];
int main(){
int T, Case=1;
scanf("%d", &T);
while(T--){
int n, m;
scanf("%d%d", &n, &m);
memset(data, 0, sizeof(data));
memset(cnt, 0, sizeof(data));
cnt[0]++;
for(int a=1; a<=n; a++){
scanf("%d", &data[a]);
data[a]=(data[a]+data[a-1])%m;
cnt[data[a]]++;
}
LL ans=0;
for(int a=0; a<m; a++){
ans+=(LL)cnt[a]*(cnt[a]-1)/2;
}
printf("Case %d: %lld\n", Case++, ans);
}
return 0;
}