【连续子段和被某数整除】SOJ 2293: The Longest SubSequence

来源:互联网 发布:数据库隔离级别和事务 编辑:程序博客网 时间:2024/06/03 20:24

You will be given a sequence consists of many numbers, your task is to calculate the length of the longest consecutive subsequence , the sum of which can be divided by another given number.

Input
There are multiple test cases.
The first line of each case contains two integer N and M, (0< N <= 100000, 0 < M < 10000),then followed by a line consists of N integers a1,a2,...an,
( -100000000 <= a1,a2,...an <= 100000000 ).

Output
For each test case,Output the length of the longest consecutive subsequence , the sum of which can be divided by M.

Sample Input

2 31 63 32 3 62 51 3

Sample Output

120

 

题目重述:求长的连续子段使其子段和能被某数整除

分析:枚举所有子段和最坏情况要O(n^2)的时间 必然超时

考虑到若用一个sum求前n个数的和 sum%m的值如果在前面出现过 则说明这一段可以整除m 

因此用一个vis数组保存余数为x的出现下标 当vis[x]被访问过 则说明i-vis[x]这一段能被整除

 

代码如下

#include <cstring>#include <cstdio>const int maxN=100000+50;int Sum;int vis[maxN];int main(){int N,M,i,temp,id,ans;while(scanf("%d%d",&N,&M)==2){memset(vis,-1,sizeof(vis));Sum=0;vis[0]=0;ans=0;for (i=1;i<=N;i++){scanf("%d",&temp);Sum+=temp;id=Sum%M;if (id<0){id+=M;}if (vis[id]==-1){vis[id]=i;}else{temp=i-vis[id];if (ans<temp){ans=temp;}}}printf("%d\n",ans);}return 0;}


 

0 0