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