给出 1个长度为 n 的序列,以及 1 个正整数 m。问这个原序列中是否存在非空子序列,使其元素之和能被 m 整除。
把多于n+1个的物体放到n个抽屉里,则至少有一个抽屉里的东西不少于两件。
代入本题中我们可以发现,当得到这个序列的n个前缀和%m时,一定会出现两个相同的数,这两个前缀和相减得到的序列和一定可以被m整除。因此,当n>m时我们可以特判为序列和一定可以被m整除,从而将n的范围从1e6缩小到1e3
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 5; int a[maxn], vis[2][10005]; int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); a[i] %= m; } vis[1][a[1]] = 1; for (int i = 2; i <= n; i++) { for (int j = 0; j < m; j++) vis[i & 1][j] = 0; for (int j = 0; j < m; j++) { vis[i & 1][j] = vis[i & 1][j] | vis[(i - 1) & 1][j]; if (vis[(i - 1) & 1][j]) vis[i & 1][(j + a[i]) % m] = 1; } vis[i & 1][a[i]] = 1; if (vis[i & 1][0]) { cout << "YES" << endl; return 0; } } if (vis[n & 1][0]) { cout << "YES" <<endl; } else { cout << "NO" << endl; } return 0; }