結果
| 問題 |
No.117 組み合わせの数
|
| ユーザー |
KoD
|
| 提出日時 | 2020-07-05 00:22:22 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 278 ms / 5,000 ms |
| コード長 | 4,429 bytes |
| コンパイル時間 | 714 ms |
| コンパイル使用メモリ | 68,984 KB |
| 最終ジャッジ日時 | 2025-01-11 15:48:20 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 1 |
ソースコード
#line 1 "main.cpp"
#define PROBLEM "https://yukicoder.me/problems/no/117"
#line 2 "/Users/kodamankod/Desktop/Programming/Library/algebraic/factorials.cpp"
#include <cstddef>
#include <array>
template <class T, size_t N>
class factorials {
public:
using value_type = T;
static constexpr size_t size = N;
public:
std::array<value_type, size + 1> fact{};
std::array<value_type, size + 1> fact_inv{};
factorials() {
fact.front() = value_type(1);
for (size_t i = 1; i <= size; ++i) {
fact[i] = fact[i - 1] * value_type(i);
}
fact_inv.back() = ~fact.back();
for (size_t i = size; i > 0; --i) {
fact_inv[i - 1] = fact_inv[i] * value_type(i);
}
}
value_type operator () (size_t n, size_t r) const {
return fact[n] * fact_inv[n - r] * fact_inv[r];
}
};
#line 2 "/Users/kodamankod/Desktop/Programming/Library/algebraic/modular.cpp"
#include <cstdint>
#include <iostream>
template <uint32_t Modulus>
class modular {
public:
using value_type = uint32_t;
using max_type = uint64_t;
static constexpr value_type mod = Modulus;
static constexpr value_type get_mod() noexcept { return mod; }
static_assert(mod >= 2, "invalid mod :: smaller than 2");
static_assert(mod < (value_type(1) << 31), "invalid mod :: over 2^31");
template <class T>
static constexpr value_type normalize(T value_) noexcept {
if (value_ < 0) {
value_ = -value_;
value_ %= mod;
if (value_ == 0) return 0;
return mod - value_;
}
return value_ % mod;
}
private:
value_type value;
public:
constexpr modular() noexcept : value(0) { }
template <class T>
explicit constexpr modular(T value_) noexcept : value(normalize(value_)) { }
template <class T>
explicit constexpr operator T() const noexcept { return static_cast<T>(value); }
constexpr value_type get() const noexcept { return value; }
constexpr modular operator - () const noexcept { return modular(mod - value); }
constexpr modular operator ~ () const noexcept { return inverse(); }
constexpr value_type &extract() noexcept { return value; }
constexpr modular inverse() const noexcept { return power(mod - 2); }
constexpr modular power(max_type exp) const noexcept {
modular res(1), mult(*this);
while (exp > 0) {
if (exp & 1) res *= mult;
mult *= mult;
exp >>= 1;
}
return res;
}
constexpr modular operator + (const modular &rhs) const noexcept { return modular(*this) += rhs; }
constexpr modular& operator += (const modular &rhs) noexcept {
if ((value += rhs.value) >= mod) value -= mod;
return *this;
}
constexpr modular operator - (const modular &rhs) const noexcept { return modular(*this) -= rhs; }
constexpr modular& operator -= (const modular &rhs) noexcept {
if ((value += mod - rhs.value) >= mod) value -= mod;
return *this;
}
constexpr modular operator * (const modular &rhs) const noexcept { return modular(*this) *= rhs; }
constexpr modular& operator *= (const modular &rhs) noexcept {
value = (max_type) value * rhs.value % mod;
return *this;
}
constexpr modular operator / (const modular &rhs) const noexcept { return modular(*this) /= rhs; }
constexpr modular& operator /= (const modular &rhs) noexcept { return (*this) *= rhs.inverse(); }
constexpr bool zero() const noexcept { return value == 0; }
constexpr bool operator == (const modular &rhs) const noexcept { return value == rhs.value; }
constexpr bool operator != (const modular &rhs) const noexcept { return value != rhs.value; }
friend std::ostream& operator << (std::ostream &stream, const modular &rhs) {
return stream << rhs.value;
}
};
#line 6 "main.cpp"
#line 8 "main.cpp"
using m32 = modular<1000000007>;
factorials<m32, 2000000> fact;
m32 comb(size_t N, size_t K) {
if (N < K) return m32(0);
return fact(N, K);
}
m32 perm(size_t N, size_t K) {
if (N < K) return m32(0);
return fact.fact[N] * fact.fact_inv[N - K];
}
m32 homo(size_t N, size_t K) {
if (N == 0 && K == 0) return m32(1);
if (N == 0) return m32(0);
return fact(N + K - 1, K);
}
int main() {
size_t T;
std::cin >> T;
while (T--) {
char type, dust;
size_t N, K;
std::cin >> type >> dust >> N >> dust >> K >> dust;
if (type == 'C') std::cout << comb(N, K) << '\n';
if (type == 'P') std::cout << perm(N, K) << '\n';
if (type == 'H') std::cout << homo(N, K) << '\n';
}
}
KoD