Problem p02974 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0; i < ((ll)(n)); i++)
#define reg(i, a, b) for (ll i = ((ll)(a)); i <= ((ll)(b)); i++)
#define irep(i, n) for (ll i = ((ll)(n)-1); i >= 0; i--)
#define ireg(i, a, b) for (ll i = ((ll)(b)); i >= ((ll)(a)); i--)

/*
またぐときにコストが発生すると考える。
dp(i,j) = i個保留、コストがjとなる場合の数
*/

template <int MOD> struct ModInt {
  static const int Mod = MOD;
  unsigned x;
  ModInt() : x(0) {}
  ModInt(signed sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  ModInt(signed long long sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  int get() const { return (int)x; }

  ModInt &operator+=(ModInt that) {
    if ((x += that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    if ((x += MOD - that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    x = (unsigned long long)x * that.x % MOD;
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }

  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }

  ModInt inverse() const {
    signed a = x, b = MOD, u = 1, v = 0;
    while (b) {
      signed t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += Mod;
    ModInt res;
    res.x = (unsigned)u;
    return res;
  }
};
typedef ModInt<1000000007> mint;

ll n, m;
mint dp[51][5001], dp2[51][5001];

void init() {
  cin >> n >> m;
  dp[0][0] = 1;
}

int main(void) {
  init();
  rep(i, n) {
    rep(j, n) {
      rep(k, n * n + 1) {
        dp2[j][k + j * 2] += dp[j][k] * 2 * j; // どのjとくっつくかで 2j 通り
        dp2[j - 1][k + j * 2] +=
            dp[j][k] * j * j; // 左右それぞれどのjを受け取るかで j^2 通り
        dp2[j][k + j * 2] += dp[j][k];     // ----
        dp2[j + 1][k + j * 2] += dp[j][k]; // 出す
      }
    }
    // cerr<<i<<endl;
    rep(j, n) {
      rep(k, n * n + 1) {
        dp[j][k] = dp2[j][k];
        dp2[j][k] = 0;
        // cerr<<dp[j][k].get()<<" ";
      }
      // cerr<<endl;
    }
  }
  cout << dp[0][m].get() << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0; i < ((ll)(n)); i++)
#define reg(i, a, b) for (ll i = ((ll)(a)); i <= ((ll)(b)); i++)
#define irep(i, n) for (ll i = ((ll)(n)-1); i >= 0; i--)
#define ireg(i, a, b) for (ll i = ((ll)(b)); i >= ((ll)(a)); i--)

/*
またぐときにコストが発生すると考える。
dp(i,j) = i個保留、コストがjとなる場合の数
*/

template <int MOD> struct ModInt {
  static const int Mod = MOD;
  unsigned x;
  ModInt() : x(0) {}
  ModInt(signed sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  ModInt(signed long long sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  int get() const { return (int)x; }

  ModInt &operator+=(ModInt that) {
    if ((x += that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    if ((x += MOD - that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    x = (unsigned long long)x * that.x % MOD;
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }

  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }

  ModInt inverse() const {
    signed a = x, b = MOD, u = 1, v = 0;
    while (b) {
      signed t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += Mod;
    ModInt res;
    res.x = (unsigned)u;
    return res;
  }
};
typedef ModInt<1000000007> mint;

ll n, m;
mint dp[51][5001], dp2[51][5001];

void init() {
  cin >> n >> m;
  dp[0][0] = 1;
}

int main(void) {
  init();
  rep(i, n) {
    rep(j, n) {
      rep(k, n * n + 1) {
        dp2[j][k + j * 2] += dp[j][k] * 2 * j; // どのjとくっつくかで 2j 通り
        if (j - 1 >= 0)
          dp2[j - 1][k + j * 2] +=
              dp[j][k] * j * j; // 左右それぞれどのjを受け取るかで j^2 通り
        dp2[j][k + j * 2] += dp[j][k];     // ----
        dp2[j + 1][k + j * 2] += dp[j][k]; // 出す
      }
    }
    // cerr<<i<<endl;
    rep(j, n) {
      rep(k, n * n + 1) {
        dp[j][k] = dp2[j][k];
        dp2[j][k] = 0;
        // cerr<<dp[j][k].get()<<" ";
      }
      // cerr<<endl;
    }
  }
  cout << dp[0][m].get() << endl;
  return 0;
}