K倍区间数 问题描述 给定一个长度为N的数列,A1, A2, … AN,如果其中一段连续的子序列 Ai, Ai 1, … Aj(i <= j)之和是K的倍数, 我们就称这个区间[i, j]是K倍区间。 你能求出数列中总共有多少个K倍区间吗? 输入格式 第一行包含两个整数N和K。(1 <= N, K <= 100000) 以下N行每行包含一个整数Ai。(1 <= Ai <= 100000) 输出格式 输出一个整数,代表K倍区间的数目。 样例输入 5 2 1 2 3 4 5 样例输出 6 数据规模和约定
思路:要求的是k的区间 而且是任意起点都可以,也就是随便截取区间只要是K的倍数即可。 那这里我们肯定得做取余运算了,如果余数为0当然是k的倍数了 那么余数不为0就不是K的倍数, 但是 仔细想一想 两个区间对k的取余结果相同,比如余数都为1时,此时这两个区间相减之后的 区间就是K的倍数了,但然这里不用担心,因为每次取到的都是连续的区间,所以减出来的区间也是连续的。 这里用到了sum来存余数x对应这个有y个区间,对于每种不同的区间他们的数量就是C(n,2), 就是n个里取两个相减,当然这里有特殊,就是余数为0的情况需要额外加1 因为 比如说S5就是K的倍数,他不需要减什么区间,但是在我们的运算中是要取到两个区间,所以要额外加1 相当于加了个 和为0的区间S0
代码语言:javascript复制#include <stdio.h>
int main()
{
long int i,n,k,j,s,s1;
long long sum[100001],js[100001]={0};
sum[0]=0;long long ans=0;
scanf("%ld%ld",&n,&k);
for(i=1;i<=n;i )scanf("%ld",&s),sum[i]=sum[i-1] s;
js[0]=1;
for(j=1;j<=n;j )js[sum[j]%k] ;
for(i=0;i<k;i )if(js[i])ans =(js[i]*(js[i]-1))/2;//C(n,2) 从 众多区间里选两个 都可构成
printf("%lldn",ans);
return 0;
}