結果
問題 | No.1667 Forest |
ユーザー | KoD |
提出日時 | 2021-09-03 22:06:52 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 85 ms / 3,000 ms |
コード長 | 5,991 bytes |
コンパイル時間 | 3,791 ms |
コンパイル使用メモリ | 254,584 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-05-09 04:12:47 |
合計ジャッジ時間 | 5,240 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 85 ms
5,248 KB |
testcase_01 | AC | 84 ms
5,248 KB |
testcase_02 | AC | 84 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 82 ms
5,376 KB |
testcase_05 | AC | 51 ms
5,376 KB |
testcase_06 | AC | 31 ms
5,376 KB |
testcase_07 | AC | 20 ms
5,376 KB |
testcase_08 | AC | 11 ms
5,376 KB |
testcase_09 | AC | 7 ms
5,376 KB |
testcase_10 | AC | 4 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 2 ms
5,376 KB |
testcase_13 | AC | 2 ms
5,376 KB |
testcase_14 | AC | 2 ms
5,376 KB |
testcase_15 | AC | 2 ms
5,376 KB |
testcase_16 | AC | 2 ms
5,376 KB |
testcase_17 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> using i32 = std::int32_t; using u32 = std::uint32_t; using i64 = std::int64_t; using u64 = std::uint64_t; using i128 = __int128_t; using u128 = __uint128_t; using isize = std::ptrdiff_t; using usize = std::size_t; class rep { struct Iter { usize itr; constexpr Iter(const usize pos) noexcept : itr(pos) {} constexpr void operator++() noexcept { ++itr; } constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; } constexpr usize operator*() const noexcept { return itr; } }; const Iter first, last; public: explicit constexpr rep(const usize first, const usize last) noexcept : first(first), last(std::max(first, last)) {} constexpr Iter begin() const noexcept { return first; } constexpr Iter end() const noexcept { return last; } }; template <class T> constexpr T rem_euclid(T value, const T& mod) { return (value %= mod) >= 0 ? value : value + mod; } template <class T> constexpr std::pair<T, T> inv_gcd(const T& a, const T& b) { using U = std::make_signed_t<T>; U t = rem_euclid(a, b); if (t == 0) return {b, 0}; U s = b, m0 = 0, m1 = 1; while (t != 0) { const U u = s / t; s -= t * u; m0 -= m1 * u; U tmp = s; s = t; t = tmp; tmp = m0; m0 = m1; m1 = tmp; } if (m0 < 0) m0 += b / s; return {(T)s, (T)m0}; } template <class T> constexpr T mod_inv(const T& a, const T& mod) { const auto [g, x] = inv_gcd(a, mod); assert(g == 1); return x; } template <usize ID> class DynamicModint { using Mint = DynamicModint; struct Barret { u32 mod; u64 near_inv; explicit Barret(const u32 mod) noexcept : mod(mod), near_inv((u64)(-1) / mod + 1) {} u32 product(const u32 a, const u32 b) const noexcept { const u64 z = (u64)a * b; const u64 x = ((u128)z * near_inv) >> 64; const u32 v = z - x * mod; return v < mod ? v : v + mod; } }; static inline auto bt = Barret(1); u32 v; public: static u32 mod() noexcept { return bt.mod; } static void set_mod(const u32 mod) noexcept { assert((u32)1 <= mod and mod <= ((u32)1 << 31)); bt = Barret(mod); } template <class T, std::enable_if_t<std::is_signed_v<T> and std::is_integral_v<T>>* = nullptr> static T normalize(const T x) noexcept { return rem_euclid<std::common_type_t<T, i64>>(x, mod()); } template <class T, std::enable_if_t<std::is_unsigned_v<T> and std::is_integral_v<T>>* = nullptr> static T normalize(const T x) noexcept { return x % mod(); } DynamicModint() noexcept : v(0) {} template <class T> DynamicModint(const T x) noexcept : v(normalize(x)) {} template <class T> static Mint raw(const T x) noexcept { Mint ret; ret.v = x; return ret; } u32 get() const noexcept { return v; } Mint neg() const noexcept { return raw(v == 0 ? 0 : mod() - v); } Mint inv() const noexcept { return raw(mod_inv(v, mod())); } Mint pow(u64 exp) const noexcept { Mint ret(1), mult(*this); for (; exp > 0; exp >>= 1) { if (exp & 1) ret *= mult; mult *= mult; } return ret; } Mint operator-() const noexcept { return neg(); } Mint operator~() const noexcept { return inv(); } Mint operator+(const Mint& rhs) const noexcept { return Mint(*this) += rhs; } Mint& operator+=(const Mint& rhs) noexcept { if ((v += rhs.v) >= mod()) v -= mod(); return *this; } Mint operator-(const Mint& rhs) const noexcept { return Mint(*this) -= rhs; } Mint& operator-=(const Mint& rhs) noexcept { if (v < rhs.v) v += mod(); v -= rhs.v; return *this; } Mint operator*(const Mint& rhs) const noexcept { return Mint(*this) *= rhs; } Mint& operator*=(const Mint& rhs) noexcept { v = bt.product(v, rhs.v); return *this; } Mint operator/(const Mint& rhs) const noexcept { return Mint(*this) /= rhs; } Mint& operator/=(const Mint& rhs) noexcept { return *this *= rhs.inv(); } bool operator==(const Mint& rhs) const noexcept { return v == rhs.v; } bool operator!=(const Mint& rhs) const noexcept { return v != rhs.v; } friend std::ostream& operator<<(std::ostream& stream, const Mint& rhs) { return stream << rhs.v; } }; using Modint = DynamicModint<__COUNTER__>; template <class T> using Vec = std::vector<T>; void main_() { usize N; u32 MOD; std::cin >> N >> MOD; Modint::set_mod(MOD); Vec<Modint> fact, inv_fact; fact.emplace_back(1); inv_fact.emplace_back(1); const auto get_fact = [&](const usize n) { while (fact.size() <= n) { fact.push_back(fact.back() * fact.size()); } return fact[n]; }; const auto get_inv_fact = [&](const usize n) { while (inv_fact.size() <= n) { inv_fact.push_back(inv_fact.back() / inv_fact.size()); } return inv_fact[n]; }; const auto binom = [&](const usize n, const usize r) { return get_fact(n) * get_inv_fact(r) * get_inv_fact(n - r); }; Vec<Modint> pre(N + 1); pre[1] = 1; for (const auto i : rep(2, N + 1)) { pre[i] = Modint(i).pow(i - 2); } Vec<Vec<Modint>> dp(N + 1, Vec<Modint>(N)); dp[0][0] = 1; for (const auto n : rep(0, N)) { for (const auto e : rep(0, N)) { if (dp[n][e].get() == 0) { continue; } for (const auto k : rep(1, N - n + 1)) { dp[n + k][e + k - 1] += dp[n][e] * binom(N - n - 1, k - 1) * pre[k]; } } } for (const auto m : rep(0, N)) { std::cout << dp[N][m] << '\n'; } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); main_(); return 0; }