Edward 得到了一个长度为 N 的整数序列,他想找出这里面有多少个“幸运的” 连续子序列。一个连续子序列被称为“幸运的”,当且仅当该子序列内的整数之 和恰好是 K 的整数倍数。他请求你写一个程序来计算他喜欢的连续子序列个数。
Edward 得到了一个长度为 N 的整数序列,他想找出这里面有多少个“幸运的” 连续子序列。一个连续子序列被称为“幸运的”,当且仅当该子序列内的整数之 和恰好是 K 的整数倍数。他请求你写一个程序来计算他喜欢的连续子序列个数。
输入第一行是一个整数 T,表示有 T 组数据。 每组数据第一行是两个整数 N (1 <= N <= 106), K (1 <= K <= 109)。 接下来的一行包含 N 个整数 Ai (|Ai| <= 109)。
对于每组测试数据,输出一行仅包含一个整数,表示 Edward 喜欢的连续子序 列数量。
2
5 3
1 2 3 4 1
6 2
1 2 1 2 1 2
4
9
链接:http://www.homeforaoge.com/problem.php?id=1210
思路:利用同余模定理,另外负数取余时,余数d=(a%K+k)%k;
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> using namespace std; #define N 1000005 #define ll long long const int inf=0x7fffffff; int s[N]; int main() { int T,i,n,k,a; ll ans,cnt; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); scanf("%d",&s[0]); s[0]%=k; if(s[0]<0) s[0]=(s[0]+k)%k; for(i=1; i<n; i++) { scanf("%d",&a); s[i]=s[i-1]+a; s[i]%=k; if(s[i]<0) s[i]=(s[i]+k)%k; } sort(s,s+n); ans=0; s[n]=inf; for(i=1,cnt=1; i<=n; i++) { if(s[i]==s[i-1]) cnt++; else { if(s[i-1]!=0) cnt--; ans+=(cnt+1)*cnt/2; cnt=1; } } printf("%lld\n",ans); } return 0; }
原文:http://www.cnblogs.com/walker11/p/4357533.html