sum

sum

Accepts: 640
Submissions: 1744
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
给定一个数列,求是否存在连续子列和为m的倍数,存在输出YES,否则输出NO
输入描述
输入文件的第一行有一个正整数T(1≤T≤101leq T leq 101T10),表示数据组数。

接下去有T组数据,每组数据的第一行有两个正整数n,m (1≤n≤100000 1leq nleq 1000001n100000 ,1≤m≤5000 1leq mleq5000 1m5000).

第二行有n个正整数x (1≤x≤1001leq xleq 1001x100)表示这个数列。
输出描述
输出T行,每行一个YES或NO。
输入样例
2
3 3
1 2 3
5 7
6 6 6 6 6
输出样例
YES
NO

预处理前缀和,一旦有两个数模m的值相同,说明中间一部分连续子列可以组成m的倍数。 另外,利用抽屉原理,我们可以得到,一旦n大于等于m,答案一定是YES 复杂度 O(n)
#include <cstdio>
#include <cstring>
int s[100010],sum[100010],vis[5001];
int main(){
    //freopen("data.in","r",stdin);
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        int flag=1; memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){scanf("%d",s+i);sum[i]=(s[i]+sum[i-1])%m;}
        for(int i=1;i<=n;i++){
            if(!vis[sum[i]]&&sum[i]!=0){
                vis[sum[i]]=1;
            }
            else{
                printf("YES
");
                flag=0;
                break;
            }
        }
        if(flag) printf("NO
");
    }
}
原文地址:https://www.cnblogs.com/acmtime/p/5744903.html