Submission #74714961


Source Code Expand

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;

template <int P>
struct ModInt {
    int v;

    constexpr ModInt() : v(0) {}
    constexpr ModInt(i64 v_) : v(v_ % P) {
        if (v < 0) {
            v += P;
        }
    }
    constexpr explicit operator int() const { return v; }
    constexpr friend ostream& operator<<(ostream &out, ModInt n) {
        return out << int(n);
    }
    constexpr friend istream& operator>>(istream &in, ModInt &n) {
        i64 v;
        in >> v;
        n = ModInt(v);
        return in;
    }

    constexpr friend bool operator==(ModInt a, ModInt b) {
        return a.v == b.v;
    }
    constexpr friend bool operator!=(ModInt a, ModInt b) {
        return a.v != b.v;
    }

    constexpr ModInt operator-() {
        ModInt res;
        res.v = v ? P - v : 0;
        return res;
    }

    constexpr ModInt& operator++() {
        v++;
        if (v == P) v = 0;
        return *this;
    }
    constexpr ModInt& operator--() {
        if (v == 0) v = P;
        v--;
        return *this;
    }
    constexpr ModInt& operator+=(ModInt o) {
        v -= P - o.v;
        v = (v < 0) ? v + P : v;
        return *this;
    }
    constexpr ModInt& operator-=(ModInt o) {
        v -= o.v;
        v = (v < 0) ? v + P : v;
        return *this;
    }
    constexpr ModInt& operator*=(ModInt o) {
        v = 1LL * v * o.v % P;
        return *this;
    }
    constexpr ModInt& operator/=(ModInt o) { return *this *= o.inv(); }

    constexpr friend ModInt operator++(ModInt &a, int) {
        ModInt r = a;
        ++a;
        return r;
    }
    constexpr friend ModInt operator--(ModInt &a, int) {
        ModInt r = a;
        --a;
        return r;
    }

    constexpr friend ModInt operator+(ModInt a, ModInt b) {
        return ModInt(a) += b;
    }
    constexpr friend ModInt operator-(ModInt a, ModInt b) {
        return ModInt(a) -= b;
    }
    constexpr friend ModInt operator*(ModInt a, ModInt b) {
        return ModInt(a) *= b;
    }
    constexpr friend ModInt operator/(ModInt a, ModInt b) {
        return ModInt(a) /= b;
    }

    constexpr ModInt qpow(i64 p) const {
        ModInt res = 1, x = v;
        while (p > 0) {
            if (p & 1) { res *= x; }
            x *= x;
            p >>= 1;
        }
        return res;
    }
    constexpr ModInt inv() const {
        return qpow(P - 2);
    }
};

constexpr int P = 998244353;
using Mint = ModInt<P>;

// < 0 return 0 ?
template <typename T>
struct Combinatorial {
    int n;
    vector<T> _fact;
    vector<T> _ifact;
    vector<T> _inv;
    
    Combinatorial() : n{0}, _fact{1}, _ifact{1}, _inv{0} {}
    
    void init(int m) {
        if (m <= n) return;
        _fact.resize(m + 1);
        _ifact.resize(m + 1);
        _inv.resize(m + 1);
        
        for (int i = n + 1; i <= m; i++) {
            _fact[i] = _fact[i - 1] * i;
        }
        _ifact[m] = T(1) / _fact[m];
        for (int i = m; i > n; i--) {
            _ifact[i - 1] = _ifact[i] * i;
            _inv[i] = _ifact[i] * _fact[i - 1];
        }
        n = m;
    }
    
    T fact(int m) {
        if (m < 0) return 0;
        if (m > n) init(2 * m);
        return _fact[m];
    }
    T ifact(int m) {
        if (m < 0) return 0;
        if (m > n) init(2 * m);
        return _ifact[m];
    }
    T inv(int m) {
        if (m < 0) return 0;
        if (m > n) init(2 * m);
        return _inv[m];
    }
    T binom(int n, int m) {
        if (n < m || m < 0) return 0;
        return fact(n) * ifact(m) * ifact(n - m);
    }
    T ibinom(int n, int m) {
        if (n < m || m < 0) return 0;
        return ifact(n) * fact(m) * fact(n - m);
    }
};

// use when not qpow
// not modint to support hash
// < 0 return 0 ?
template <typename T>
struct Powers {
    T base, invbase;
    int n;
    vector<T> _pow;
    vector<T> _ipow;
    
    Powers(T v) : base(v), invbase(v.inv()), n{0}, _pow{T(1)}, _ipow{T(1)} {}
    
    void init(int m) {
        if (m <= n) return;
        _pow.resize(m + 1);
        _ipow.resize(m + 1);
        
        for (int i = n + 1; i <= m; i++) {
            _pow[i] = _pow[i - 1] * base;
            _ipow[i] = _ipow[i - 1] * invbase;
        }
        n = m;
    }
    
    T pow(int m) {
        if (m < 0) return 0;
        if (m > n) init(2 * m);
        return _pow[m];
    }
    T ipow(int m) {
        if (m < 0) return 0;
        if (m > n) init(2 * m);
        return _ipow[m];
    }
    // unsafe
    T get(int m) {
        return m >= 0 ? pow(m) : ipow(-m);
    }
};

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    auto solve = [&]() {
        int n, C;
        cin >> n >> C;

        vector<int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }

        sort(a.begin(), a.end());

        vector<Mint> p(n + 1);
        p[0] = a.front() - 1;
        for (int i = 1; i < n; i++) {
            p[i] = a[i] - a[i - 1];
        }
        p[n] = C - a.back() + 1;
        for (int i = 0; i <= n; i++) {
            p[i] /= C;
        }

        vector dp(n + 1, vector<Mint>(n + 1));
        dp[0][0] = 1;
        Combinatorial<Mint> comb;
        
        for (int i = n; i >= 0; i--) {
            Powers<Mint> pw(p[i]);
            vector ndp(n + 1, vector<Mint>(n + 1));
            for (int x = 0; x <= n; x++) {
                for (int y = 0; y <= x; y++) {
                    for (int z = 0; x + z <= n; z++) {
                        ndp[x + z][max(0, y + z - (i != 0))] += pw.pow(z) * comb.ifact(z) * dp[x][y];
                    }
                }
            }
            dp = move(ndp);
        }

        vector<Mint> ans(n + 1);
        for (int y = 0; y <= n; y++) {
            ans[n - y] += dp[n][y] * comb.fact(n);
        }

        for (int k = 0; k <= n; k++) {
            cout << ans[k] << " \n"[k == n];
        }
    };

    int t;
    cin >> t;

    while (t--) {
        solve();
    }
    
    return 0;
}

Submission Info

Submission Time
Task C - Greedy Customers 2
User rgnerdplayer
Language C++23 (GCC 15.2.0)
Score 700
Code Size 6222 Byte
Status AC
Exec Time 53 ms
Memory 3728 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 700 / 700
Status
AC × 1
AC × 27
Set Name Test Cases
Sample 00_sample_00.txt
All 00_sample_00.txt, 01_handmade_00.txt, 01_handmade_01.txt, 01_handmade_02.txt, 01_handmade_03.txt, 02_random_00.txt, 02_random_01.txt, 02_random_02.txt, 02_random_03.txt, 02_random_04.txt, 02_random_05.txt, 02_random_06.txt, 02_random_07.txt, 02_random_08.txt, 02_random_09.txt, 02_random_10.txt, 02_random_11.txt, 02_random_12.txt, 02_random_13.txt, 02_random_14.txt, 02_random_15.txt, 02_random_16.txt, 02_random_17.txt, 02_random_18.txt, 02_random_19.txt, 02_random_20.txt, 02_random_21.txt
Case Name Status Exec Time Memory
00_sample_00.txt AC 1 ms 3596 KiB
01_handmade_00.txt AC 53 ms 3700 KiB
01_handmade_01.txt AC 52 ms 3696 KiB
01_handmade_02.txt AC 52 ms 3580 KiB
01_handmade_03.txt AC 1 ms 3452 KiB
02_random_00.txt AC 1 ms 3452 KiB
02_random_01.txt AC 1 ms 3400 KiB
02_random_02.txt AC 52 ms 3576 KiB
02_random_03.txt AC 52 ms 3528 KiB
02_random_04.txt AC 52 ms 3720 KiB
02_random_05.txt AC 52 ms 3728 KiB
02_random_06.txt AC 52 ms 3704 KiB
02_random_07.txt AC 52 ms 3728 KiB
02_random_08.txt AC 52 ms 3700 KiB
02_random_09.txt AC 52 ms 3692 KiB
02_random_10.txt AC 52 ms 3728 KiB
02_random_11.txt AC 52 ms 3668 KiB
02_random_12.txt AC 52 ms 3720 KiB
02_random_13.txt AC 52 ms 3644 KiB
02_random_14.txt AC 52 ms 3704 KiB
02_random_15.txt AC 52 ms 3692 KiB
02_random_16.txt AC 52 ms 3692 KiB
02_random_17.txt AC 52 ms 3576 KiB
02_random_18.txt AC 52 ms 3696 KiB
02_random_19.txt AC 52 ms 3624 KiB
02_random_20.txt AC 52 ms 3700 KiB
02_random_21.txt AC 52 ms 3644 KiB