提出 #41422173


ソースコード 拡げる

#include <iostream>
#include <vector>
#include <chrono>
#include <random>
#include <cassert>

std::mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count());

const int MOD = 998244353;

template <class T, class E>
constexpr T fexp(T x, E e) {
    T ans(1);
    for(; e > 0; e >>= 1) {
        if(e & 1) ans = ans * x;
        x = x * x;
    }
    return ans;
}

template <class LOW, class HIGH, const LOW mod>
struct modBase {
    using mint = modBase<LOW, HIGH, mod>;
    constexpr modBase() : val(0) {}
    // be careful of negative numbers!
    constexpr modBase(const LOW v) : val((v % mod + mod) % mod) {} 
    LOW val;

    #define add(a, b) a + b >= mod ? a + b - mod : a + b
    #define sub(a, b) a < b ? a + mod - b : a - b

    constexpr mint &operator += (const mint &o) { return val = add(val, o.val), *this; }
    constexpr mint &operator -= (const mint &o) { return val = sub(val, o.val), *this; }
    constexpr mint &operator *= (const mint &o) { return val = (LOW) ((HIGH) val * o.val % mod), *this; }
    constexpr mint &operator /= (const mint &o) { return *this *= o.inverse(); }

    constexpr mint operator + (const mint &b) const { return mint(*this) += b; }
    constexpr mint operator - (const mint &b) const { return mint(*this) -= b; }
    constexpr mint operator * (const mint &b) const { return mint(*this) *= b; }
    constexpr mint operator / (const mint &b) const { return mint(*this) /= b; }

    constexpr mint operator - () const { return mint() - mint(*this); }
    constexpr bool operator == (const mint &b) const { return val == b.val; }
    constexpr bool operator != (const mint &b) const { return val != b.val; }

    template<class E> constexpr mint pow (E e) const { return fexp(*this, e); }
    constexpr mint inverse() const { return pow(mod - 2); }
    constexpr LOW get() const { return val; }
    static constexpr LOW getMod() { return mod; }

    friend std::ostream& operator << (std::ostream &os, const mint &p) { return os << p.val; }
    friend std::istream& operator >> (std::istream &is, mint &p) { return is >> p.val; }
};

using mint = modBase<long long, long long, MOD>;

const int ms = 4020;

mint fat[ms], ifat[ms];
void initComb() {
    fat[0] = 1;
    for(int i = 1; i < ms; i++) {
        fat[i] = fat[i-1] * i;
    }
    ifat[ms-1] = fexp(fat[ms-1], MOD - 2);
    for(int i = ms-1; i > 0; i--) {
        ifat[i-1] = ifat[i] * i;
    }
}
mint comb(int n, int a) { return a < 0 || a > n ? mint() : fat[n] * ifat[a] * ifat[n-a]; }
mint bigComb(long long n, int a) {
    assert(n >= 0 && a >= 0 && a <= n);
    n %= MOD;
    //std::cout << "comb(" << n << ", " << a << ")\n";
    if(n < a) {
        //std::cout << "corner\n";
        return 0;
    }
    mint ans = ifat[a];
    //std::cout << "start with " << ans << '\n';
    for(int i = 0; i < a; i++) {
        assert((n - i + MOD) <= 2e9);
        mint cur((n - i + MOD) % MOD);
        assert(cur.val == n - i);
        ans *= cur;
        //std::cout << "multiplied by " << cur << " got " << ans << '\n';
    }
    return ans;
}

mint solve(int n, int k, long long ops) {
    if(ops < 0) {
        return 0;
    }
    // mint ans(0);
    // for(int i = 0; i <= ops; i++) {
    //     ans += comb(n-1+ops-i, n-1) * comb(n-k+i, n-k);
    // }
    // return ans;
    return bigComb(2 * n - k + ops, 2 * n - k);
}

int main() {
    std::ios_base::sync_with_stdio(false); std::cin.tie(NULL);
    initComb();
    int k, n;
    long long ops;
    std::cin >> n >> ops >> k;
    if(ops % k != 0) {
        std::cout << "0\n";
        return 0;
    }
    ops /= k;
    mint ans(0);
    //std::cout << "there are " << ops << " ops\n";
    for(int i = 0; i <= n - k + 1; i++) {
        //std::cout << "for i " << i << " operating " << solve(n, k, ops - k * i) << " * " << comb(n - k + 1, i) << '\n';
        mint cur = solve(n, k, ops - k * i) * comb(n - k + 1, i);
        if(i % 2 == 0) {
            ans += cur;
        } else {
            ans -= cur;
        }
        //break;
    }
    std::cout << ans << '\n';
}

提出情報

提出日時
問題 D - Mahjong
ユーザ tfg
言語 C++ (GCC 9.2.1)
得点 700
コード長 4173 Byte
結果 AC
実行時間 37 ms
メモリ 3600 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 700 / 700
結果
AC × 3
AC × 41
セット名 テストケース
Sample example_00.txt, example_01.txt, example_02.txt
All example_00.txt, example_01.txt, example_02.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt
ケース名 結果 実行時間 メモリ
example_00.txt AC 1 ms 3524 KiB
example_01.txt AC 2 ms 3540 KiB
example_02.txt AC 26 ms 3552 KiB
test_00.txt AC 36 ms 3552 KiB
test_01.txt AC 8 ms 3548 KiB
test_02.txt AC 11 ms 3600 KiB
test_03.txt AC 4 ms 3552 KiB
test_04.txt AC 4 ms 3532 KiB
test_05.txt AC 2 ms 3536 KiB
test_06.txt AC 2 ms 3576 KiB
test_07.txt AC 2 ms 3576 KiB
test_08.txt AC 2 ms 3572 KiB
test_09.txt AC 2 ms 3520 KiB
test_10.txt AC 2 ms 3528 KiB
test_11.txt AC 2 ms 3544 KiB
test_12.txt AC 2 ms 3556 KiB
test_13.txt AC 2 ms 3552 KiB
test_14.txt AC 2 ms 3536 KiB
test_15.txt AC 2 ms 3552 KiB
test_16.txt AC 2 ms 3576 KiB
test_17.txt AC 12 ms 3540 KiB
test_18.txt AC 12 ms 3492 KiB
test_19.txt AC 10 ms 3572 KiB
test_20.txt AC 28 ms 3552 KiB
test_21.txt AC 2 ms 3552 KiB
test_22.txt AC 24 ms 3552 KiB
test_23.txt AC 19 ms 3552 KiB
test_24.txt AC 11 ms 3600 KiB
test_25.txt AC 19 ms 3544 KiB
test_26.txt AC 17 ms 3536 KiB
test_27.txt AC 18 ms 3552 KiB
test_28.txt AC 17 ms 3492 KiB
test_29.txt AC 37 ms 3596 KiB
test_30.txt AC 31 ms 3536 KiB
test_31.txt AC 36 ms 3556 KiB
test_32.txt AC 3 ms 3552 KiB
test_33.txt AC 4 ms 3496 KiB
test_34.txt AC 5 ms 3540 KiB
test_35.txt AC 8 ms 3556 KiB
test_36.txt AC 8 ms 3544 KiB
test_37.txt AC 11 ms 3556 KiB