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行,每行一个YES或NO。
输入样例
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;
}