Submission #69905504


Source Code Expand

#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif

template <class T, class U = T> bool chmin(T& x, U&& y) { return y < x and (x = std::forward<U>(y), true); }

template <class T, class U = T> bool chmax(T& x, U&& y) { return x < y and (x = std::forward<U>(y), true); }

template <class T> void mkuni(std::vector<T>& v) {
    std::ranges::sort(v);
    auto result = std::ranges::unique(v);
    v.erase(result.begin(), result.end());
}

template <class T> int lwb(const std::vector<T>& v, const T& x) {
    return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}

#include <atcoder/modint>

template <typename T> struct Binomial {
    Binomial(int MAX = 0) : n(1), facs(1, T(1)), finvs(1, T(1)), invs(1, T(1)) {
        assert(T::mod() != 0);
        if (MAX > 0) extend(MAX + 1);
    }

    T fac(int i) {
        assert(i >= 0);
        while (n <= i) extend();
        return facs[i];
    }

    T finv(int i) {
        assert(i >= 0);
        while (n <= i) extend();
        return finvs[i];
    }

    T inv(int i) {
        assert(i >= 0);
        while (n <= i) extend();
        return invs[i];
    }

    T P(int n, int r) {
        if (n < r or r < 0) return 0;
        return fac(n) * finv(n - r);
    }

    T C(int n, int r) {
        if (n < r or r < 0) return 0;
        return fac(n) * finv(n - r) * finv(r);
    }

    T H(int n, int r) {
        if (n < 0 or r < 0) return 0;
        return r == 0 ? 1 : C(n + r - 1, r);
    }

    T negative_binom(int n, int k) { return H(k, n); }

    T C_naive(int n, int r) {
        if (n < r or r < 0) return 0;
        T res = 1;
        r = std::min(r, n - r);
        for (int i = 1; i <= r; i++) res *= inv(i) * (n--);
        return res;
    }

    T catalan(int n) {
        if (n < 0) return 0;
        return fac(2 * n) * finv(n + 1) * finv(n);
    }

    T catalan_pow(int n, int k) {
        if (n < 0 or k < 0) return 0;
        if (k == 0) return n == 0 ? 1 : 0;
        return inv(n + k) * k * C(2 * n + k - 1, n);
    }

    T calatan1(int n, int m) { return C(n + m, m) - C(n + m, m - 1); }

    T catalan2(int n, int m, int k) { return n - m <= -k ? 0 : C(n + m, m) - C(n + m, m - k); }

    T narayana(int n, int k) {
        if (n < k or k <= 0) return 0;
        return C(n, k) * C(n, k - 1) * inv(n);
    }

    T grid_sum(int x, int y) {
        if (x < 0 or y < 0) return 0;
        return C(x + y + 2, x + 1) - 1;
    }

    T grid_sum2(int xl, int xr, int yl, int yr) {
        if (xl >= xr or yl >= yr) return 0;
        xl--, xr--, yl--, yr--;
        return grid_sum(xr, yr) - grid_sum(xl, yr) - grid_sum(xr, yl) + grid_sum(xl, yl);
    }

  private:
    int n;
    std::vector<T> facs, finvs, invs;

    inline void extend(int m = -1) {
        if (m == -1) m = n * 2;
        m = std::min(m, T::mod());
        if (n >= m) return;
        facs.resize(m);
        finvs.resize(m);
        invs.resize(m);
        for (int i = n; i < m; i++) facs[i] = facs[i - 1] * i;
        finvs[m - 1] = T(1) / facs[m - 1];
        invs[m - 1] = finvs[m - 1] * facs[m - 2];
        for (int i = m - 2; i >= n; i--) {
            finvs[i] = finvs[i + 1] * (i + 1);
            invs[i] = finvs[i] * facs[i - 1];
        }
        n = m;
    }
};

using namespace std;

using ll = long long;

using mint = atcoder::modint998244353;
Binomial<mint> BINOM;

void solve() {
    int N, X;
    cin >> N >> X;
    vector<int> a(N);
    for (int i = 0; i < N; i++) {
        cin >> a[i];
    }

    ll need = accumulate(a.begin(), a.end(), 0LL) - X;
    if (need <= 0) {
        cout << BINOM.fac(N).val() << "\n";
        return;
    }
    if (need > N * (N - 1) / 2) {
        cout << 0 << "\n";
        return;
    }
    X = need;

    vector<int> cnt(N + 1, 0);
    for (int x : a) {
        if (x <= N) {
            cnt[x]++;
        }
    }
    vector dp(N + 1, vector<mint>(X + 1, 0)), ndp(N + 1, vector<mint>(X + 1, 0));
    dp[0][0] = 1;
    int sum = 0;
    for (int k = 0; k < N; k++) {
        for (int i = 0; i <= k; i++) {
            for (int j = 0; j <= need; j++) {
                mint& val = dp[i][j];
                if (val == 0) {
                    continue;
                }
                int usable = k - i, add = cnt[k];
                for (int d = 0; d <= min(usable, add); d++) {
                    ndp[i + d][min(X, j + k * (add - d))] += val * BINOM.P(usable, d) * BINOM.C(add, d);
                }
                val = 0;
            }
        }
        swap(dp, ndp);
        sum += cnt[k];
        for (int i = 0; i <= k; i++) {
            for (int j = 0; j <= need; j++) {
                mint& val = dp[i][j];
                if (val == 0) {
                    continue;
                }
                if (i < sum) {
                    ndp[i + 1][j] += val * (sum - i);
                }
                ndp[i][min(X, j + k)] += val;
                val = 0;
            }
        }
        swap(dp, ndp);
    }

    mint ans = dp[sum][need] * BINOM.fac(N - sum);
    cout << ans.val() << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    solve();
    return 0;
}

Submission Info

Submission Time
Task A - Affinity for Artifacts
User rniya
Language C++ 23 (gcc 12.2)
Score 800
Code Size 5411 Byte
Status AC
Exec Time 70 ms
Memory 7104 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 800 / 800
Status
AC × 3
AC × 47
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All hand_01.txt, hand_02.txt, hand_03.txt, hand_04.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, sample_01.txt, sample_02.txt, sample_03.txt, small_01.txt, small_02.txt, small_03.txt, small_04.txt, small_05.txt, small_06.txt, small_07.txt, small_08.txt, small_09.txt, small_10.txt, small_11.txt, small_12.txt, small_13.txt, small_14.txt, small_15.txt, small_16.txt, small_17.txt, small_18.txt, small_19.txt, small_20.txt
Case Name Status Exec Time Memory
hand_01.txt AC 1 ms 3476 KiB
hand_02.txt AC 1 ms 3620 KiB
hand_03.txt AC 1 ms 3328 KiB
hand_04.txt AC 1 ms 3540 KiB
random_01.txt AC 70 ms 6952 KiB
random_02.txt AC 65 ms 6724 KiB
random_03.txt AC 67 ms 7104 KiB
random_04.txt AC 66 ms 6448 KiB
random_05.txt AC 68 ms 7100 KiB
random_06.txt AC 68 ms 7032 KiB
random_07.txt AC 69 ms 6952 KiB
random_08.txt AC 68 ms 6996 KiB
random_09.txt AC 68 ms 6684 KiB
random_10.txt AC 64 ms 6420 KiB
random_11.txt AC 36 ms 5176 KiB
random_12.txt AC 10 ms 3884 KiB
random_13.txt AC 2 ms 3660 KiB
random_14.txt AC 1 ms 3488 KiB
random_15.txt AC 30 ms 5100 KiB
random_16.txt AC 10 ms 3780 KiB
random_17.txt AC 2 ms 3588 KiB
random_18.txt AC 1 ms 3524 KiB
random_19.txt AC 45 ms 5976 KiB
random_20.txt AC 10 ms 3832 KiB
sample_01.txt AC 1 ms 3444 KiB
sample_02.txt AC 1 ms 3472 KiB
sample_03.txt AC 1 ms 3444 KiB
small_01.txt AC 1 ms 3452 KiB
small_02.txt AC 1 ms 3484 KiB
small_03.txt AC 1 ms 3376 KiB
small_04.txt AC 1 ms 3620 KiB
small_05.txt AC 1 ms 3464 KiB
small_06.txt AC 1 ms 3448 KiB
small_07.txt AC 1 ms 3612 KiB
small_08.txt AC 1 ms 3424 KiB
small_09.txt AC 1 ms 3488 KiB
small_10.txt AC 1 ms 3336 KiB
small_11.txt AC 1 ms 3492 KiB
small_12.txt AC 1 ms 3496 KiB
small_13.txt AC 1 ms 3480 KiB
small_14.txt AC 1 ms 3428 KiB
small_15.txt AC 1 ms 3488 KiB
small_16.txt AC 1 ms 3484 KiB
small_17.txt AC 1 ms 3436 KiB
small_18.txt AC 1 ms 3528 KiB
small_19.txt AC 1 ms 3476 KiB
small_20.txt AC 1 ms 3388 KiB