HDU 5776 sum (数组前缀和+取模)

sum

问题描述

给定一个数列,求是否存在连续子列和为m的倍数,存在输出YES,否则输出NO

输入描述

输入文件的第一行有一个正整数T(1≤T≤101\leq T \leq 101≤T≤10),表示数据组数。

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

第二行有n个正整数x 1≤x≤1001\leq x\leq 1001≤x≤100)表示这个数列。

输出描述

输出T行,每行一个YESNO

输入样例

2

3 3

1 2 3

5 7

6 6 6 6 6

输出样例

YES

NO

思路 ~
把所有数组的和取模后的存到a[i],遍历一遍如果a[i]==0或者a[i]==a[j]成立则输出YES 否则输出NO     PS :a[j]为另一个a[i],暂时叫a[j]吧。
原理  1. a[i]==0; 从1到i 连续一段,就是从1到i和取模等于0成立,很好理解
         2.a[i]==a[j];从1到i 中间某一段,可以满足和取模等于0 成立。假设 sum[1,i]%m=k,sum[1,j]%m=k,(i<j),则a[1,j]-sum[1,i]等于N倍k,所以sum[i+1,j]%m=0。

//#include <bits/stdc++.h>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
int main(){
    int n,m,t;
    int a[100090];
    int x;
    int flag;
    int sum;
    cin>>t;
    while (t--) {
        sum=0;
        flag=0;
        cin>>n>>m;
        for (int i=1; i<=n; i++) {
            cin>>x;
            sum+=x;
            a[i]=sum%m;
        }
        for (int i=1; i<=n; i++) {
            for (int j=1; j<=n&&i!=j; j++) {
                if(a[i]==0||(a[i]==a[j])){
                    flag=1;
                    break;
                }
            }
        }
        if(flag) cout<<"YES"<<endl;
        
        else
            cout<<"NO"<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值