Modulo Sum(背包 + STL)

 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;
}

  

posted @ 2016-04-12 17:29  handsomecui  阅读(391)  评论(0编辑  收藏  举报