Problem p03398 (C++)

Buggy submission (status: Runtime Error):
#include <cassert>
#include <functional>
#include <iostream>
#include <vector>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++(i))
using namespace std;
template <typename X, typename T> auto vectors(X x, T a) {
  return vector<T>(x, a);
}
template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
  auto cont = vectors(y, z, zs...);
  return vector<decltype(cont)>(x, cont);
}

template <int32_t MOD> struct mint {
  int64_t value;                          // faster than int32_t a little
  mint() = default;                       // value is not initialized
  mint(int64_t value_) : value(value_) {} // assume value is in proper range
  inline mint<MOD> operator+(mint<MOD> other) const {
    int64_t c = this->value + other.value;
    return mint<MOD>(c >= MOD ? c - MOD : c);
  }
  inline mint<MOD> operator-(mint<MOD> other) const {
    int64_t c = this->value - other.value;
    return mint<MOD>(c < 0 ? c + MOD : c);
  }
  inline mint<MOD> operator*(mint<MOD> other) const {
    int64_t c = this->value * int64_t(other.value) % MOD;
    return mint<MOD>(c < 0 ? c + MOD : c);
  }
  inline mint<MOD> &operator+=(mint<MOD> other) {
    this->value += other.value;
    if (this->value >= MOD)
      this->value -= MOD;
    return *this;
  }
  inline mint<MOD> &operator-=(mint<MOD> other) {
    this->value -= other.value;
    if (this->value < 0)
      this->value += MOD;
    return *this;
  }
  inline mint<MOD> &operator*=(mint<MOD> other) {
    this->value = this->value * int64_t(other.value) % MOD;
    if (this->value < 0)
      this->value += MOD;
    return *this;
  }
  mint<MOD> pow(uint64_t k) const {
    mint<MOD> x = *this;
    mint<MOD> y = 1;
    for (uint64_t i = 1; i and (i <= k); i <<= 1) {
      if (k & i)
        y *= x;
      x *= x;
    }
    return y;
  }
  mint<MOD> inv() const { return pow(MOD - 2); } // MOD must be a prime
};

template <int32_t MOD> mint<MOD> fact(int n) {
  static vector<mint<MOD>> memo(1, 1);
  while (n >= memo.size()) {
    memo.push_back(memo.back() * mint<MOD>(memo.size()));
  }
  return memo[n];
}
template <int32_t PRIME> mint<PRIME> inv_fact(int n) {
  static vector<mint<PRIME>> memo;
  if (memo.size() <= n) {
    int l = memo.size();
    int r = n * 1.3 + 100;
    memo.resize(r);
    memo[r - 1] = fact<PRIME>(r - 1).inv();
    for (int i = r - 2; i >= l; --i) {
      memo[i] = memo[i + 1] * (i + 1);
    }
  }
  return memo[n];
}

template <int32_t MOD> mint<MOD> choose(int n, int r) {
  assert(0 <= r and r <= n);
  return fact<MOD>(n) * inv_fact<MOD>(n - r) * inv_fact<MOD>(r);
}

constexpr int MOD = 1e9 + 7;

mint<MOD> solve(int n) {
  auto used = vectors(n + 1, n, n, n + 1, (char)false);
  auto memo = vectors(n + 1, n, n, n + 1, mint<MOD>());
  function<mint<MOD>(int, int, int, int)> dp = [&](int k, int pos, int neg,
                                                   int cnt) -> mint<MOD> {
    if (pos + neg == 0)
      return (cnt == 0);
    if (pos + neg > cnt)
      return 0;
    assert(k <= n);
    char &used1 = used[k][pos][neg][cnt];
    auto &memo1 = memo[k][pos][neg][cnt];
    if (used1)
      return memo1;
    used1 = true;
    REP(pos1, cnt + 1) {
      REP(neg1, cnt + 1) {
        int pos2 = pos + neg1 - pos1;
        int neg2 = neg + pos1 - neg1;
        if (0 <= pos2 and 0 <= neg2 and pos2 + neg2 <= cnt) {
          memo1 += dp(k + 1, pos1, neg1, cnt - pos2 - neg2) *
                   choose<MOD>(cnt, pos2) * choose<MOD>(cnt - pos2, neg2);
        }
      }
    }
    return memo1;
  };
  return dp(0, 1, 0, n);
}

int main() {
  int n;
  cin >> n;
  cout << solve(n).value << endl;
  return 0;
}


Fixed submission:
#include <cassert>
#include <functional>
#include <iostream>
#include <vector>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++(i))
using namespace std;
template <typename X, typename T> auto vectors(X x, T a) {
  return vector<T>(x, a);
}
template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
  auto cont = vectors(y, z, zs...);
  return vector<decltype(cont)>(x, cont);
}

template <int32_t MOD> struct mint {
  int64_t value;                          // faster than int32_t a little
  mint() = default;                       // value is not initialized
  mint(int64_t value_) : value(value_) {} // assume value is in proper range
  inline mint<MOD> operator+(mint<MOD> other) const {
    int64_t c = this->value + other.value;
    return mint<MOD>(c >= MOD ? c - MOD : c);
  }
  inline mint<MOD> operator-(mint<MOD> other) const {
    int64_t c = this->value - other.value;
    return mint<MOD>(c < 0 ? c + MOD : c);
  }
  inline mint<MOD> operator*(mint<MOD> other) const {
    int64_t c = this->value * int64_t(other.value) % MOD;
    return mint<MOD>(c < 0 ? c + MOD : c);
  }
  inline mint<MOD> &operator+=(mint<MOD> other) {
    this->value += other.value;
    if (this->value >= MOD)
      this->value -= MOD;
    return *this;
  }
  inline mint<MOD> &operator-=(mint<MOD> other) {
    this->value -= other.value;
    if (this->value < 0)
      this->value += MOD;
    return *this;
  }
  inline mint<MOD> &operator*=(mint<MOD> other) {
    this->value = this->value * int64_t(other.value) % MOD;
    if (this->value < 0)
      this->value += MOD;
    return *this;
  }
  mint<MOD> pow(uint64_t k) const {
    mint<MOD> x = *this;
    mint<MOD> y = 1;
    for (uint64_t i = 1; i and (i <= k); i <<= 1) {
      if (k & i)
        y *= x;
      x *= x;
    }
    return y;
  }
  mint<MOD> inv() const { return pow(MOD - 2); } // MOD must be a prime
};

template <int32_t MOD> mint<MOD> fact(int n) {
  static vector<mint<MOD>> memo(1, 1);
  while (n >= memo.size()) {
    memo.push_back(memo.back() * mint<MOD>(memo.size()));
  }
  return memo[n];
}
template <int32_t PRIME> mint<PRIME> inv_fact(int n) {
  static vector<mint<PRIME>> memo;
  if (memo.size() <= n) {
    int l = memo.size();
    int r = n * 1.3 + 100;
    memo.resize(r);
    memo[r - 1] = fact<PRIME>(r - 1).inv();
    for (int i = r - 2; i >= l; --i) {
      memo[i] = memo[i + 1] * (i + 1);
    }
  }
  return memo[n];
}

template <int32_t MOD> mint<MOD> choose(int n, int r) {
  assert(0 <= r and r <= n);
  return fact<MOD>(n) * inv_fact<MOD>(n - r) * inv_fact<MOD>(r);
}

constexpr int MOD = 1e9 + 7;

mint<MOD> solve(int n) {
  auto used = vectors(n + 1, max(2, n), n, n + 1, (char)false);
  auto memo = vectors(n + 1, max(2, n), n, n + 1, mint<MOD>());
  function<mint<MOD>(int, int, int, int)> dp = [&](int k, int pos, int neg,
                                                   int cnt) -> mint<MOD> {
    if (pos + neg == 0)
      return (cnt == 0);
    if (pos + neg > cnt)
      return 0;
    assert(k <= n);
    char &used1 = used[k][pos][neg][cnt];
    auto &memo1 = memo[k][pos][neg][cnt];
    if (used1)
      return memo1;
    used1 = true;
    REP(pos1, cnt + 1) {
      REP(neg1, cnt + 1) {
        int pos2 = pos + neg1 - pos1;
        int neg2 = neg + pos1 - neg1;
        if (0 <= pos2 and 0 <= neg2 and pos2 + neg2 <= cnt) {
          memo1 += dp(k + 1, pos1, neg1, cnt - pos2 - neg2) *
                   choose<MOD>(cnt, pos2) * choose<MOD>(cnt - pos2, neg2);
        }
      }
    }
    return memo1;
  };
  return dp(0, 1, 0, n);
}

int main() {
  int n;
  cin >> n;
  cout << solve(n).value << endl;
  return 0;
}