您的位置:首页 > 其它

Modulo Sum(背包 + STL)

2016-04-12 17:29 316 查看
Modulo Sum

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

You are given a sequence of numbers a1, a2, ..., an, and a number m.

Check if it is possible to choose a non-empty subsequence aij such that the sum of numbers in this subsequence is divisible bym.

Input
The first line contains two numbers, n and m (1 ≤ n ≤ 106, 2 ≤ m ≤ 103) — the size of the original sequence and the number such that sum should be divisible by it.

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

Output
In the single line print either "YES" (without the quotes) if there exists the sought subsequence, or "NO" (without the quotes), if such subsequence doesn't exist.

Examples

input
3 5 1 2 3


output
YES


input
1 6 5


output
NO


input
4 6 3 1 1 3


output
YES


input
6 6 5 5 5 5 5 5


output
YES


Note
In the first sample test you can choose numbers 2 and 3, the sum of which is divisible by 5.

In the second sample test the single non-empty subsequence of numbers is a single number 5. Number 5 is not divisible by 6, that is, the sought subsequence doesn't exist.

In the third sample test you need to choose two numbers 3 on the ends.

In the fourth sample test you can take the whole subsequence.

题意:

取任意个数的和能否组成M的倍数;宇神用背包写的,参谋了下,很聪明的解法,还可以用set做;

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1e3 + 100;
int num[MAXN * MAXN];
int v[MAXN * MAXN];
int dp[25 * MAXN][MAXN];
int val[MAXN * MAXN];
int main(){
int n, m;
while(~scanf("%d%d", &n, &m)){
memset(num, 0, sizeof(num));
memset(v, 0, sizeof(v));
memset(dp, 0, sizeof(dp));
memset(val, 0, sizeof(val));
int tp = 0;
int temp;
int ans = 0;
for(int i = 0; i < n; i++){
scanf("%d", &temp);
if(temp == m){
ans = 1;
}
if(!num[temp % m])
v[tp++] = temp % m;
num[temp % m]++;
}
n = tp;
/*
printf("tp = %d\n",tp);
for(int i = 0; i < tp; i++){
printf("v = %d num = %d \n", v[i], num[v[i] ]);
}puts("");
*/
tp = 0;
for(int i = 0; i < n; i++){
for(int j = 1; j <= num[v[i]]; j <<= 1){
if(j * v[i] % m == 0){
ans = 1;
}
num[v[i]] -= j;
val[tp++] = j * v[i] % m;
}
if(num[v[i]] > 0){
if(v[i] * num[v[i]] % m == 0)
ans = 1;
val[tp++] = v[i] * num[v[i]] % m;
}
}
/*
printf("tp = %d\n",tp);
for(int i = 0; i < tp; i++){
printf("v = %d num = %d \n", val[i], num[v[i] ]);
}puts("");
*/
dp[0][v[0]] = 1;dp[0][0] = 1;
//    printf("ans = %d\n",ans);
for(int i = 0; i < tp - 1; i++){
for(int j = 0; j <= m; j++){
if(dp[i][j]){
//    printf("i = %d j = %d\n",i,j);
dp[i + 1][j] = 1;
if((j + val[i + 1]) % m == 0){
ans = 1;
}
dp[i + 1][(j + val[i + 1]) % m] = 1;
}
}
}
if(ans)puts("YES");
else puts("NO");
}
return 0;
}


set:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
const int MAXN = 1e6 + 100;
int main(){
int n, m;
while(~scanf("%d%d", &n, &m)){
int temp, ans = 0;
set<int>st, _st;
st.insert(0);
set<int>::iterator iter;
for(int i = 0; i < n; i++){
scanf("%d", &temp);
for(iter = st.begin(); iter != st.end(); iter++){
if((*iter + temp) % m == 0){
printf("YES\n");
return 0;
}
_st.insert((*iter + temp) % m);
}
st.insert(_st.begin(), _st.end());
_st.clear();
}
puts("NO");
}
return 0;
}


vector:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<vector>
using namespace std;
const int MAXN = 1e6 + 100;
int vis[MAXN];
int main(){
int n, m;
while(~scanf("%d%d", &n, &m)){
int temp, ans = 0;
vector<int>st, _st;
st.push_back(0);
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++){
scanf("%d", &temp);
if(ans)continue;
for(int i = 0; i < st.size(); i++){
int x = (st[i] + temp) % m;
if(x == 0){
ans = 1;
break;
}
if(!vis[x])vis[x] = 1,_st.push_back(x);
}
for(int i = 0; i < _st.size(); i++){
st.push_back(_st[i]);
}
_st.clear();
}
if(ans)puts("YES");
else puts("NO");
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: