Problem p02862 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

using ll = int64_t;
using Vi = vector<int>;
using Vl = vector<ll>;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;

constexpr int I_INF = INT_MAX;
constexpr ll L_INF = LLONG_MAX;

//===

constexpr int64_t MOD = static_cast<int64_t>(1e9 + 7);

// ModInt
//
// 宣言:
// ModInt<1000000007> mi;
// ModInt<1000000007> mi(917856986);
//
template <std::int_fast64_t Modulus> class ModInt {
  using i64 = std::int_fast64_t;

public:
  i64 a;

  constexpr ModInt(const i64 x = 0) noexcept : a(x % Modulus) {}

  constexpr i64 &value() noexcept { return a; }
  constexpr const i64 &value() const noexcept { return a; }

  constexpr ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }

  constexpr ModInt &operator+=(const ModInt rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    i64 exp = Modulus - 2;
    while (exp) {
      if (exp & 1) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp >>= 1;
    }
    return *this;
  }

  constexpr ModInt &operator++() noexcept {
    *this += 1;
    return *this;
  }
  constexpr ModInt operator++(int) noexcept {
    ModInt res = *this;
    *this += 1;
    return res;
  }
  constexpr ModInt &operator--() noexcept {
    *this -= 1;
    return *this;
  }
  constexpr ModInt operator--(int) noexcept {
    ModInt res = *this;
    *this -= 1;
    return res;
  }

  constexpr bool operator<(const ModInt &rhs) const noexcept {
    return a < rhs.a;
  }
  constexpr bool operator>(const ModInt &rhs) const noexcept {
    return a > rhs.a;
  }
  constexpr bool operator<=(const ModInt &rhs) const noexcept {
    return a <= rhs.a;
  }
  constexpr bool operator>=(const ModInt &rhs) const noexcept {
    return a >= rhs.a;
  }
  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return a == rhs.a;
  }

  constexpr ModInt pow(i64 k) const noexcept {
    ModInt res = 1;
    ModInt tmp = *this;
    for (; k > 0; k >>= 1) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
    }
    return res;
  }

  constexpr ModInt inverse() const noexcept {
    i64 q = a;
    i64 b = Modulus, u = 1, v = 0;
    while (b) {
      i64 t = q / b;
      q -= t * b;
      swap(q, b);
      u -= t * v;
      swap(u, v);
    }
    u %= Modulus;
    if (u < 0)
      u += Modulus;
    return u;
  }
};

// 二項係数(mod)
// 要ModInt
template <std::int_fast64_t Modulus> class ModComb {
  using i64 = int_fast64_t;
  using Vl = std::vector<i64>;

private:
  Vl fac, inv, finv;

public:
  ModComb(i64 n) : fac(n + 1), inv(n + 1), finv(n + 1) {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (i64 i = 2; i < n + 1; ++i) {
      fac[i] = fac[i - 1] * i % Modulus;
      inv[i] = Modulus - inv[Modulus % i] * (Modulus / i) % Modulus;
      finv[i] = finv[i - 1] * inv[i] % Modulus;
    }
  }

  ModInt<Modulus> comb(i64 n, i64 k) {
    ModInt<Modulus> res;
    if (n < k)
      res = 0;
    else if (n < 0 || k < 0)
      res = 0;
    else
      res = fac[n] * (finv[n - k] * finv[k] % Modulus) % Modulus;
    return res;
  }

  ModInt<Modulus> get_fac(i64 n) { return ModInt<Modulus>(fac[n]); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int x, y;
  cin >> x >> y;

  if ((x + y) % 3 != 0) {
    cout << 0 << endl;
    return 0;
  }

  int n1, n2;
  int n;

  n2 = (2 * x - y) / 3;
  n1 = (x + y) / 3 - n2;
  n = n1 + n2;

  ModComb<MOD> mc(n);
  ModInt<MOD> ans;

  ans = mc.get_fac(n) / (mc.get_fac(n1) * mc.get_fac(n2));

  cout << ans.value() << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

using ll = int64_t;
using Vi = vector<int>;
using Vl = vector<ll>;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;

constexpr int I_INF = INT_MAX;
constexpr ll L_INF = LLONG_MAX;

//===

constexpr int64_t MOD = static_cast<int64_t>(1e9 + 7);

// ModInt
//
// 宣言:
// ModInt<1000000007> mi;
// ModInt<1000000007> mi(917856986);
//
template <std::int_fast64_t Modulus> class ModInt {
  using i64 = std::int_fast64_t;

public:
  i64 a;

  constexpr ModInt(const i64 x = 0) noexcept : a(x % Modulus) {}

  constexpr i64 &value() noexcept { return a; }
  constexpr const i64 &value() const noexcept { return a; }

  constexpr ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }

  constexpr ModInt &operator+=(const ModInt rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    i64 exp = Modulus - 2;
    while (exp) {
      if (exp & 1) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp >>= 1;
    }
    return *this;
  }

  constexpr ModInt &operator++() noexcept {
    *this += 1;
    return *this;
  }
  constexpr ModInt operator++(int) noexcept {
    ModInt res = *this;
    *this += 1;
    return res;
  }
  constexpr ModInt &operator--() noexcept {
    *this -= 1;
    return *this;
  }
  constexpr ModInt operator--(int) noexcept {
    ModInt res = *this;
    *this -= 1;
    return res;
  }

  constexpr bool operator<(const ModInt &rhs) const noexcept {
    return a < rhs.a;
  }
  constexpr bool operator>(const ModInt &rhs) const noexcept {
    return a > rhs.a;
  }
  constexpr bool operator<=(const ModInt &rhs) const noexcept {
    return a <= rhs.a;
  }
  constexpr bool operator>=(const ModInt &rhs) const noexcept {
    return a >= rhs.a;
  }
  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return a == rhs.a;
  }

  constexpr ModInt pow(i64 k) const noexcept {
    ModInt res = 1;
    ModInt tmp = *this;
    for (; k > 0; k >>= 1) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
    }
    return res;
  }

  constexpr ModInt inverse() const noexcept {
    i64 q = a;
    i64 b = Modulus, u = 1, v = 0;
    while (b) {
      i64 t = q / b;
      q -= t * b;
      swap(q, b);
      u -= t * v;
      swap(u, v);
    }
    u %= Modulus;
    if (u < 0)
      u += Modulus;
    return u;
  }
};

// 二項係数(mod)
// 要ModInt
template <std::int_fast64_t Modulus> class ModComb {
  using i64 = int_fast64_t;
  using Vl = std::vector<i64>;

private:
  Vl fac, inv, finv;

public:
  ModComb(i64 n) : fac(n + 1), inv(n + 1), finv(n + 1) {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (i64 i = 2; i < n + 1; ++i) {
      fac[i] = fac[i - 1] * i % Modulus;
      inv[i] = Modulus - inv[Modulus % i] * (Modulus / i) % Modulus;
      finv[i] = finv[i - 1] * inv[i] % Modulus;
    }
  }

  ModInt<Modulus> comb(i64 n, i64 k) {
    ModInt<Modulus> res;
    if (n < k)
      res = 0;
    else if (n < 0 || k < 0)
      res = 0;
    else
      res = fac[n] * (finv[n - k] * finv[k] % Modulus) % Modulus;
    return res;
  }

  ModInt<Modulus> get_fac(i64 n) { return ModInt<Modulus>(fac[n]); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int x, y;
  cin >> x >> y;

  if ((x + y) % 3 != 0) {
    cout << 0 << endl;
    return 0;
  }

  int n1, n2;
  int n;

  n2 = (2 * x - y) / 3;
  n1 = (x + y) / 3 - n2;

  if (min(n1, n2) < 0) {
    cout << 0 << endl;
    return 0;
  }

  n = n1 + n2;

  ModComb<MOD> mc(n);
  ModInt<MOD> ans;

  ans = mc.get_fac(n) / (mc.get_fac(n1) * mc.get_fac(n2));

  cout << ans.value() << endl;

  return 0;
}