Problem p02625 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <array>
#include <bitset>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;

// 整数型
using ll = int_fast64_t;
using i32 = int_fast32_t;
using i64 = int_fast64_t;
using u32 = uint_fast32_t;
using u64 = uint_fast64_t;
// [0,n)を昇順/降順でループ
#define rep(i, n) for (int i = 0; i < static_cast<int>(n); ++i)
#define repd(i, n) for (int i = static_cast<int>(n) - 1; i >= 0; --i)
// [a,b)を昇順/降順でループ
#define FOR(i, a, b)                                                           \\
  for (int i = static_cast<int>(a); i < static_cast<int>(b); ++i)
#define FORD(i, a, b)                                                          \\
  for (int i = static_cast<int>(b) - 1; i >= static_cast<int>(a); --i)

// デバッグ
#ifdef DEBUG
#include <cassert>
#define my_assert(x) assert(x)
#else
#define my_assert(x)
#endif

template <u32 p> struct mint {
  // p は素数
  static_assert(1 < p and p < (static_cast<u32>(1) << 31),
                "p must be in [2, 2 ** 31)");

private:
  // [0,p)内の値
  u32 data;

  constexpr static inline i64 p_i64 = static_cast<i64>(p);

public:
  // safe
  constexpr mint() noexcept : data(0) {}

  constexpr mint(i64 const x) noexcept
      : data(static_cast<u32>((x % p_i64 >= 0) ? x % p_i64
                                               : x % p_i64 + p_i64)) {}

  // unsafe
  constexpr mint(u32 const x, bool const) noexcept : data(x) {}

  // convert to u32
  constexpr u32 const &val() const noexcept { return data; }

  constexpr mint &operator+=(mint const x) noexcept {
    data += x.data;
    if (data >= p) {
      data -= p;
    }
    return *this;
  }

  constexpr mint &operator-=(mint const x) noexcept {
    if (data < x.data) {
      data += p;
    }
    data -= x.data;
    return *this;
  }

  constexpr mint &operator*=(mint const x) noexcept {
    data = static_cast<u32>(static_cast<u64>(data) * x.data % p);
    return *this;
  }

  constexpr mint &operator/=(mint x) {
    if (x.data == 0) {
      throw domain_error("Division by mint zero");
    }
    u32 exp = p - 2;
    // (*this) * (x ** exp) : invariant
    while (exp > 0) {
      if (exp & 1) {
        *this *= x;
      }
      x *= x;
      exp /= 2;
    }
    return *this;
  }

  constexpr mint &operator++() noexcept { return *this += mint(1, true); }

  constexpr mint operator++(int) noexcept {
    mint const ret(*this);
    ++(*this);
    return ret;
  }

  constexpr mint &operator--() noexcept { return *this -= mint(1, true); }

  constexpr mint operator--(int) noexcept {
    mint const ret(*this);
    --(*this);
    return ret;
  }

  constexpr mint operator-() const noexcept { return mint(0, true) -= *this; }

  constexpr mint operator+(mint const x) const noexcept {
    return mint(*this) += x;
  }

  constexpr mint operator-(mint const x) const noexcept {
    return mint(*this) -= x;
  }

  constexpr mint operator*(mint const x) const noexcept {
    return mint(*this) *= x;
  }

  constexpr mint operator/(mint const x) const { return mint(*this) /= x; }

  // x >= 0 のときべき乗を計算
  constexpr mint pow(u64 const x) const noexcept {
    u64 exp = x;
    mint ret(1, true), base(*this);
    // ret * (base ** exp) : invariant, == (*this) ** x
    while (exp > 0) {
      if (exp & 1) {
        ret *= base;
      }
      base *= base;
      exp /= 2;
    }
    return ret;
  }

  constexpr mint inv() const noexcept { return mint(1, true) /= *this; }

  constexpr bool operator==(mint const x) const noexcept {
    return data == x.data;
  }
};

//////////////// //////////////// //////////////// ////////////////
///////////////////
//////////////// //////////////// //////////////// ////////////////
///////////////////

constexpr u32 mod = 1000'000'007u;

int main() {
  // 高速な入出力
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  // 浮動小数の表示の精度
  cout << setprecision(15);

  int n, m;
  cin >> n >> m;
  vector<mint<mod>> fact(m + 1), factinv(m + 1);
  fact[0] = mint<mod>(1, true);
  factinv[0] = mint<mod>(1, true);
  FOR(i, 1, m + 1) {
    fact[i] = fact[i - 1] * mint<mod>(i, true);
    factinv[i] = fact[i].inv();
  }

  mint<mod> ans;
  rep(k, n + 1) {
    auto a = fact[n] * factinv[k] * factinv[n - k];
    auto b = mint<mod>((k & 1) ? -1 : 1);
    auto c = fact[m] * factinv[m - n];
    auto d = fact[m - k] * factinv[m - n];
    ans += a * b * c * d;
  }
  cout << ans.val() << endl;

  return 0;
}


Error: -6
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>    // assert
#include <cmath>      // abs など
#include <functional> // greater など
#include <iostream>
#include <map>
#include <numeric> // accumulate など
#include <queue>
#include <set>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;
// typedef int128_t ll;
// typedef cpp_int ll;

// GCC, 配列のアクセスなど
#define _GLIBCXX_DEBUG
// Clang, 配列のアクセスなど
#define _LIBCPP_DEBUG 0

// #define NDEBUG 1
// debug用出力 https://trap.jp/post/998/
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << H << " ";
  debug_out(T...);
}
#ifdef NDEBUG
#define debug(...)
#else
#define debug(...) debug_out(__VA_ARGS__)
#endif

//////////////// //////////////// //////////////// ////////////////
///////////////////
//////////////// //////////////// //////////////// ////////////////
///////////////////

constexpr inline ll MOD = 1'000'000'007;
// constexpr inline int max_n = 500000 + 9;
constexpr inline int max_n = 5000 + 9;
vector<vector<ll>> dp(max_n, vector<ll>(max_n));
vector<ll> factmemo(max_n);

int main() {
  // 入出力
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  factmemo[0] = 1;
  REP(i, max_n - 1) { factmemo[i + 1] = factmemo[i] * (i + 1) % MOD; }

  ll n, m;
  cin >> n >> m;

  REP(j, m + 1) {
    dp[j][0] = 1;
    dp[j][1] = j - 1;
    REP(i, j - 1) {
      dp[j][i + 2] = ((i + 1) * factmemo[j - i - 1] % MOD * dp[j - 1][i] % MOD +
                      (j - i - 2) * dp[j - 1][i + 1] % MOD) %
                     MOD;
    }
  }

  debug(dp[m][n]);
  cout << dp[m][n] * factmemo[m] / factmemo[m - n] % MOD << endl;

  return 0;
}