結果

問題 No.117 組み合わせの数
ユーザー maine_honzukimaine_honzuki
提出日時 2020-05-16 23:09:12
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 268 ms / 5,000 ms
コード長 2,771 bytes
コンパイル時間 1,753 ms
コンパイル使用メモリ 174,112 KB
実行使用メモリ 19,292 KB
最終ジャッジ日時 2023-10-24 05:10:22
合計ジャッジ時間 2,880 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 268 ms
19,292 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;

template <uint MD>
struct ModInt {
    using M = ModInt;
    const static M G;
    uint v;
    ModInt(long long _v = 0) { set_v(_v % MD + MD); }
    M& set_v(uint _v) {
        v = (_v < MD) ? _v : _v - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v((unsigned long long)(v)*r.v % MD); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    M pow(long long n) const {
        M x = *this, r = 1;
        while (n) {
            if (n & 1)
                r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    M inv() const { return pow(MD - 2); }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
    friend istream& operator>>(istream& is, M& r) { return is >> r.v; }
};
using Mint = ModInt<MOD>;
const int MN = 2'000'010;
Mint fact[MN], iFac[MN];

void first() {
    fact[0] = Mint(1);
    for (int i = 1; i < MN; i++)
        fact[i] = fact[i - 1] * Mint(i);
    iFac[MN - 1] = fact[MN - 1].inv();
    for (int i = MN - 1; i >= 1; i--) {
        iFac[i - 1] = iFac[i] * Mint(i);
    }
    assert(fact[2345] * iFac[2345] == Mint(1));
}
Mint C(int n, int k) {
    if (n < k || k < 0)
        return Mint(0);
    return fact[n] * iFac[k] * iFac[n - k];
}

int main() {
    first();
    int T;
    cin >> T;
    while (T--) {
        string S;
        cin >> S;
        char c = S[0];
        S = S.substr(2);
        S.pop_back();
        stringstream ss(S);
        string item;
        vector<int> A;
        while (getline(ss, item, ',')) {
            if (!item.empty())
                A.push_back(stoi(item));
        }
        if (c == 'C') {
            if (A[0] >= A[1])
                cout << C(A[0], A[1]) << endl;
            else
                cout << 0 << endl;
        } else if (c == 'P') {
            if (A[0] >= A[1])
                cout << fact[A[0]] * iFac[A[0] - A[1]] << endl;
            else
                cout << 0 << endl;

        } else if (A[0] >= 1)
            cout << C(A[0] + A[1] - 1, A[1]) << endl;
        else if (A[1] == 0)
            cout << 1 << endl;
        else
            cout << 0 << endl;
    }
}
0