Problem p02862 (C++)

Buggy submission (status: Runtime Error):
#ifdef DEBUG

#else

#pragma GCC optimize("O3,no-stack-protector")
#pragma GCC optimize("unroll-loops")

#if __cplusplus >= 201703L
#pragma GCC target("avx2")
#else
#pragma GCC target("avx")
#endif

#endif
// 実数の場合
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define dump(x) cout << x << endl
typedef int64_t Int;
typedef long double Ld;

using namespace std;
using Graph = vector<vector<Int>>;

const double pi = M_PI;
const Int MOD = 1000000007;

// 二分累乗法
template <typename T> T modpow(T a, T n, T mod) {
  T ret = 1;

  if (mod == 1) {
    while (n > 0) {
      if (n & 1) {
        ret = ret * a;
      }
      a = a * a;
      n >>= 1;
    }
  } else {
    while (n > 0) {
      if (n & 1) {
        ret = ret * a % mod;
      }
      a = a * a % mod;
      n >>= 1;
    }
  }

  return ret;
}

vector<Int> factorials, invs;
bool is_ncr_table = false;
// modが素数の場合のみ
void calc_ncr_table(Int n, Int mod) {
  is_ncr_table = true;

  // 1! ~ n! の計算
  Int f = 1;
  factorials.push_back(f);
  for (Int i = 1; i <= n; i++) {
    f *= i;
    f %= mod;
    factorials.push_back(f);
  }

  // n!^-1 の計算
  Int inv = modpow(factorials[n], mod - 2, mod);
  // (n-1)!^-1 ~ 1!^-1 の計算
  invs.assign(n, 1);
  invs[n] = inv;
  for (Int i = n; i >= 1; i--) {
    inv *= i;
    inv %= mod;
    invs[i - 1] = inv;
  }
}

// 一度だけnCrを計算するとき用の関数
Int factorial(Int n, Int mod = 1) {
  Int ret = 1;
  if (mod == 1) {
    for (Int i = 1; i <= n; i++) {
      ret *= i;
    }

    return ret;
  } else {
    for (Int i = 1; i <= n; i++) {
      ret *= i;
      ret %= mod;
    }

    return ret;
  }
}

Int ncr(Int n, Int r, Int mod) {
  if (n < r) {
    return (Int)0;
  } else {
    if (is_ncr_table) {
      // modが素数の場合のみ
      return (factorials[n] * invs[r] % mod) * invs[n - r] % mod;
    } else {
      Int x = 1;
      for (Int i = n - r + 1; i <= n; i++) {
        x *= i;
        x %= mod;
      }
      return x * modpow(factorial(r, mod), mod - 2, mod) % mod;
    }
  }
}

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

  calc_ncr_table(1000005LL, MOD);

  Int x, y;
  cin >> x >> y;

  Int n, m;
  n = (2 * y - x) / 3;
  m = (2 * x - y) / 3;

  Int ans;
  if ((x + y) % 3 != 0) {
    ans = 0;
  } else {
    ans = ncr(n + m, n, MOD);
  }

  cout << ans << endl;

  return 0;
}


Fixed submission:
#ifdef DEBUG

#else

#pragma GCC optimize("O3,no-stack-protector")
#pragma GCC optimize("unroll-loops")

#if __cplusplus >= 201703L
#pragma GCC target("avx2")
#else
#pragma GCC target("avx")
#endif

#endif
// 実数の場合
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define dump(x) cout << x << endl
typedef int64_t Int;
typedef long double Ld;

using namespace std;
using Graph = vector<vector<Int>>;

const double pi = M_PI;
const Int MOD = 1000000007;

// 二分累乗法
template <typename T> T modpow(T a, T n, T mod) {
  T ret = 1;

  if (mod == 1) {
    while (n > 0) {
      if (n & 1) {
        ret = ret * a;
      }
      a = a * a;
      n >>= 1;
    }
  } else {
    while (n > 0) {
      if (n & 1) {
        ret = ret * a % mod;
      }
      a = a * a % mod;
      n >>= 1;
    }
  }

  return ret;
}

vector<Int> factorials, invs;
bool is_ncr_table = false;
// modが素数の場合のみ
void calc_ncr_table(Int n, Int mod) {
  is_ncr_table = true;

  // 1! ~ n! の計算
  Int f = 1;
  factorials.push_back(f);
  for (Int i = 1; i <= n; i++) {
    f *= i;
    f %= mod;
    factorials.push_back(f);
  }

  // n!^-1 の計算
  Int inv = modpow(factorials[n], mod - 2, mod);
  // (n-1)!^-1 ~ 1!^-1 の計算
  invs.assign(n, 1);
  invs[n] = inv;
  for (Int i = n; i >= 1; i--) {
    inv *= i;
    inv %= mod;
    invs[i - 1] = inv;
  }
}

// 一度だけnCrを計算するとき用の関数
Int factorial(Int n, Int mod = 1) {
  Int ret = 1;
  if (mod == 1) {
    for (Int i = 1; i <= n; i++) {
      ret *= i;
    }

    return ret;
  } else {
    for (Int i = 1; i <= n; i++) {
      ret *= i;
      ret %= mod;
    }

    return ret;
  }
}

Int ncr(Int n, Int r, Int mod) {
  if (n < r) {
    return (Int)0;
  } else {
    if (is_ncr_table) {
      // modが素数の場合のみ
      return (factorials[n] * invs[r] % mod) * invs[n - r] % mod;
    } else {
      Int x = 1;
      for (Int i = n - r + 1; i <= n; i++) {
        x *= i;
        x %= mod;
      }
      return x * modpow(factorial(r, mod), mod - 2, mod) % mod;
    }
  }
}

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

  calc_ncr_table(1000005LL, MOD);

  Int x, y;
  cin >> x >> y;

  Int n, m;
  n = (2 * y - x) / 3;
  m = (2 * x - y) / 3;

  Int ans;
  if ((x + y) % 3 != 0 || (n < 0 || m < 0)) {
    ans = 0;
  } else {
    ans = ncr(n + m, n, MOD);
  }

  cout << ans << endl;

  return 0;
}