【题目】
1907: k倍区间
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 50 Solved: 22
[Submit][Status][Web Board]
Description
给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
Input
每个数据包含多组输入数据
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
Output
输出一个整数,代表K倍区间的数目。
Sample Input
5 2
1
2
3
4
5
Sample Output
6
【题解】
一开始以为就是简单前缀和的问题然后因为O(n*n)的话就超时了,讲道理我还是不太会计算时间复杂度,要改正!!
思路:在前缀和的基础上对k取余,这样的话数组a[]的数据范围就是[0,k-1],那么k倍区间就是(a[r]-a[l-1])%k==0即a[r]==a[l-1]时的区间,所以只要寻找有多少对a[r]与a[l-1]相等即可。
【代码】
#include <stdio.h>
#include <string.h>
main()
{
int n,k,i;
int a[100005],vis[100005];
while(~scanf("%d%d",&n,&k))
{
memset(a,0,sizeof(a));
memset(vis,0,sizeof(vis));
vis[0]=1;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]=(a[i]+a[i-1])%k;
}
int ans=0;
for(i=1;i<=n;i++)
{
ans+=vis[a[i]];
vis[a[i]]++;
}
printf("%d\n",ans);
}
}