Problem p02974 (C++)

Buggy submission (status: Runtime Error):
#include <cstdint>
#include <cstdlib>
#include <iostream>
template <typename T> void fin(T const &t) {
  std::cout << t << std::endl;
  exit(0);
}

// mint
int64_t const MOD = 1e9 + 7;

template <int64_t Prime> struct mod_int {
  int64_t v_;
  mod_int(int64_t x = 0) : v_(x) { normalize(); }
  void normalize() { ((v_ %= Prime) += Prime) %= Prime; }
  mod_int operator+=(mod_int const &r) {
    (v_ += r.v_) %= Prime;
    return *this;
  }
  mod_int operator-=(mod_int const &r) {
    (v_ += Prime - r.v_) %= Prime;
    return *this;
  }
  mod_int operator*=(mod_int const &r) {
    (v_ *= r.v_) %= Prime;
    return *this;
  }
  mod_int operator+(mod_int const &r) {
    mod_int res(*this);
    return res += r;
  }
  mod_int operator-(mod_int const &r) {
    mod_int res(*this);
    return res -= r;
  }
  mod_int operator*(mod_int const &r) {
    mod_int res(*this);
    return res *= r;
  }
  mod_int pow(int x) const {
    int64_t res = 1, v = v_;
    while (x > 0) {
      if (x & 1)
        (res *= v) %= Prime;
      x /= 2;
      (v *= v) %= Prime;
    }
    return mod_int(res);
  }
  mod_int inv() const { return pow(Prime - 2); }
};
typedef mod_int<MOD> mint;

// optional
template <typename T> struct optional {
  bool valid;
  T v_;
  optional() : valid(false) {}
  optional &operator=(T const &v) {
    v_ = v;
    valid = true;
    return *this;
  }
  T &operator*() { return v_; }
  T const &operator*() const { return v_; }
};

int const MAXN = 50;
int const MAXK = MAXN * MAXN;

optional<mint> dp[MAXN][MAXN][MAXK];

mint calc(int i, int j, int k) {
  if (dp[i][j][k].valid)
    return *dp[i][j][k];
  mint res;
  int new_k = k - j - j;
  if (new_k >= 0 && i >= 1) {
    if (i - 1 >= j)
      res += mint(j + j + 1) * calc(i - 1, j, new_k);
    if (i - 2 >= j)
      res += mint(j + 1) * (j + 1) * calc(i - 1, j + 1, new_k);
    if (i >= j && j >= 1)
      res += calc(i - 1, j - 1, new_k);
  }
  return *(dp[i][j][k] = res);
}

int main() {
  int n, k;
  std::cin >> n >> k;
  dp[0][0][0] = 1;
  fin(calc(n, 0, k).v_);
  return 0;
}


Fixed submission:
#include <cstdint>
#include <cstdlib>
#include <iostream>
template <typename T> void fin(T const &t) {
  std::cout << t << std::endl;
  exit(0);
}

// mint
int64_t const MOD = 1e9 + 7;

template <int64_t Prime> struct mod_int {
  int64_t v_;
  mod_int(int64_t x = 0) : v_(x) { normalize(); }
  void normalize() { ((v_ %= Prime) += Prime) %= Prime; }
  mod_int operator+=(mod_int const &r) {
    (v_ += r.v_) %= Prime;
    return *this;
  }
  mod_int operator-=(mod_int const &r) {
    (v_ += Prime - r.v_) %= Prime;
    return *this;
  }
  mod_int operator*=(mod_int const &r) {
    (v_ *= r.v_) %= Prime;
    return *this;
  }
  mod_int operator+(mod_int const &r) {
    mod_int res(*this);
    return res += r;
  }
  mod_int operator-(mod_int const &r) {
    mod_int res(*this);
    return res -= r;
  }
  mod_int operator*(mod_int const &r) {
    mod_int res(*this);
    return res *= r;
  }
  mod_int pow(int x) const {
    int64_t res = 1, v = v_;
    while (x > 0) {
      if (x & 1)
        (res *= v) %= Prime;
      x /= 2;
      (v *= v) %= Prime;
    }
    return mod_int(res);
  }
  mod_int inv() const { return pow(Prime - 2); }
};
typedef mod_int<MOD> mint;

// optional
template <typename T> struct optional {
  bool valid;
  T v_;
  optional() : valid(false) {}
  optional &operator=(T const &v) {
    v_ = v;
    valid = true;
    return *this;
  }
  T &operator*() { return v_; }
  T const &operator*() const { return v_; }
};

int const MAXN = 50;
int const MAXK = MAXN * MAXN;

optional<mint> dp[MAXN + 1][MAXN + 1][MAXK + 1];

mint calc(int i, int j, int k) {
  if (dp[i][j][k].valid)
    return *dp[i][j][k];
  mint res;
  int new_k = k - j - j;
  if (new_k >= 0 && i >= 1) {
    if (i - 1 >= j)
      res += mint(j + j + 1) * calc(i - 1, j, new_k);
    if (i - 2 >= j)
      res += mint(j + 1) * (j + 1) * calc(i - 1, j + 1, new_k);
    if (i >= j && j >= 1)
      res += calc(i - 1, j - 1, new_k);
  }
  return *(dp[i][j][k] = res);
}

int main() {
  int n, k;
  std::cin >> n >> k;
  dp[0][0][0] = 1;
  fin(calc(n, 0, k).v_);
  return 0;
}