题意转化一下就是:
给出一列数a[1]...a[n],求长度最长的一段连续的数,使得这些数的和能被M整除。
分析:
设这列数前i项和为s[i],
则一段连续的数的和 a[i]+a[i+1]+...+a[j-1]+a[j]=s[j]-s[i-1],
所以这段连续的数的和能被m整除的条件就是 (s[j]-s[i-1]) % m == 0,
即 s[j]%m-s[i-1]%m == 0,
因此,只需要每一个余数找使s[i]%m等于该余数的最小的i,和s[j]%m等于该余数的最大的j,相减即为最长的连续的数的长度。
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
#define N 100005
int a[N],sum[N];
int vis[10005],b[10005];
int main()
{
int n,m,mod,i,j,max=0;
while(~scanf("%d%d",&n,&m))
{
sum[0]=0;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]=(a[i]%m+m)%m;
sum[i]=(sum[i-1]+a[i])%m;
}
vis[0] = 1;b[0] = 0;
max=0;
for(i=1;i<=n;i++)
{
mod=sum[i]%m;
if(!vis[mod])
{
vis[mod]=1; b[mod]=i;
}
else
{
max=max>(i-b[mod])?max:(i-b[mod]);
}
}
printf("%d\n",max);
}
return 0;
}