CF577B-Modulo Sum
Modulo Sum
思路
抽屉原理+01背包。
1.\(n>m\)时,n个前缀和中一定会出现两个前缀和相同(在模m的剩余系中),所以一定会有解。
2.\(n<=m\)时,由于\(m\leq 1000\),可以暴力做01背包。
3.若\(m\)很大,可以用多重背包二进制优化+map来做。
Code:
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=1e6+10;
const int M=1e3+10;
int q[2000005];
bitset<M>dp;
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",&q[i]);
q[i]=q[i]%m;
}
if(n>m){//抽屉原理
puts("YES");
return 0;
}
bitset<M>wc;
for(int i=1;i<=n;++i){
for(int j=0;j<=m;++j){
wc[j]=dp[((j-q[i])+m)%m];
}
wc[q[i]]=1;
dp|=wc;
wc.reset();
}
if(dp[m]||dp[0])puts("YES");
else puts("NO");
return 0;
}