Problem p03332 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define OUT(x) cout << (x) << endl;
#define OUTA(a, n)                                                             \
  REP(i, n) { cout << (a[i]) << (i == n - 1 ? "\n" : " "); }
#define ALL(a) (a).begin(), (a).end()
#define SORT(a) sort(ALL(a))
#define RSORT(a)                                                               \
  SORT(a);                                                                     \
  reverse(ALL(a))

const ll INF = 1e18;
const ll MOD = 998244353;

class mint {
public:
  ll a;

  mint(const ll x = 0) : a(x % MOD) {}
  ll &value() { return a; }
  mint pow(ll rhs) {
    ll exp = rhs;
    mint res = mint(1);
    mint p = mint(a);
    while (exp) {
      if (exp & 1) {
        res *= p;
      }
      exp >>= 1;
      p *= p;
    }
    return res;
  }
  mint pow(mint rhs) { return pow(rhs.a); }
  mint &operator+=(ll rhs) {
    a += rhs;
    if (a >= MOD) {
      a -= MOD;
    }
    return *this;
  }
  mint &operator+=(mint rhs) {
    *this += rhs.a;
    return *this;
  }
  mint &operator-=(ll rhs) {
    if (a < rhs) {
      a += MOD;
    }
    a -= rhs;
    return *this;
  }
  mint &operator-=(mint rhs) {
    *this -= rhs.a;
    return *this;
  }
  mint &operator*=(ll rhs) {
    a = a * rhs % MOD;
    return *this;
  }
  mint &operator*=(mint rhs) {
    *this *= rhs.a;
    return *this;
  }
  mint &operator/=(ll rhs) {
    *this *= mint(rhs).pow(MOD - 2);
    return *this;
  }
  mint &operator/=(mint rhs) {
    *this /= rhs.a;
    return *this;
  }
};

mint operator+(const mint &lhs, const mint &rhs) { return mint(lhs.a) += rhs; }
mint operator+(const mint &lhs, const ll &rhs) { return mint(lhs.a) += rhs; }
mint operator+(const ll &lhs, const mint &rhs) { return mint(lhs) += rhs; }
mint operator-(const mint &lhs, const mint &rhs) { return mint(lhs.a) -= rhs; }
mint operator-(const mint &lhs, const ll &rhs) { return mint(lhs.a) -= rhs; }
mint operator-(const ll &lhs, const mint &rhs) { return mint(lhs) -= rhs; }
mint operator*(const mint &lhs, const mint &rhs) { return mint(lhs.a) *= rhs; }
mint operator*(const mint &lhs, const ll &rhs) { return mint(lhs.a) *= rhs; }
mint operator*(const ll &lhs, const mint &rhs) { return mint(lhs) *= rhs; }
mint operator/(const mint &lhs, const mint &rhs) { return mint(lhs.a) /= rhs; }
mint operator/(const mint &lhs, const ll &rhs) { return mint(lhs.a) /= rhs; }
mint operator/(const ll &lhs, const mint &rhs) { return mint(lhs) /= rhs; }

ll N, A, B, K;

int main() {
  cin >> N >> A >> B >> K;

  vector<mint> fact = vector<mint>(N + 1);
  fact[0] = mint(1);
  REP(i, N) { fact[i + 1] = (i + 1) * fact[i]; }
  auto comb = [&](ll n, ll r) { return fact[n] / (fact[r] * fact[n - r]); };

  mint ans = mint(0);
  REP(i, N + 1) {
    ll r = K - i * A;
    if (r >= 0 and r % B == 0) {
      ans += comb(N, i) * comb(N, r / B);
    }
  }

  OUT(ans.a);
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define OUT(x) cout << (x) << endl;
#define OUTA(a, n)                                                             \
  REP(i, n) { cout << (a[i]) << (i == n - 1 ? "\n" : " "); }
#define ALL(a) (a).begin(), (a).end()
#define SORT(a) sort(ALL(a))
#define RSORT(a)                                                               \
  SORT(a);                                                                     \
  reverse(ALL(a))

const ll INF = 1e18;
const ll MOD = 998244353;

class mint {
public:
  ll a;

  mint(const ll x = 0) : a(x % MOD) {}
  ll &value() { return a; }
  mint pow(ll rhs) {
    ll exp = rhs;
    mint res = mint(1);
    mint p = mint(a);
    while (exp) {
      if (exp & 1) {
        res *= p;
      }
      exp >>= 1;
      p *= p;
    }
    return res;
  }
  mint pow(mint rhs) { return pow(rhs.a); }
  mint &operator+=(ll rhs) {
    a += rhs;
    if (a >= MOD) {
      a -= MOD;
    }
    return *this;
  }
  mint &operator+=(mint rhs) {
    *this += rhs.a;
    return *this;
  }
  mint &operator-=(ll rhs) {
    if (a < rhs) {
      a += MOD;
    }
    a -= rhs;
    return *this;
  }
  mint &operator-=(mint rhs) {
    *this -= rhs.a;
    return *this;
  }
  mint &operator*=(ll rhs) {
    a = a * rhs % MOD;
    return *this;
  }
  mint &operator*=(mint rhs) {
    *this *= rhs.a;
    return *this;
  }
  mint &operator/=(ll rhs) {
    *this *= mint(rhs).pow(MOD - 2);
    return *this;
  }
  mint &operator/=(mint rhs) {
    *this /= rhs.a;
    return *this;
  }
};

mint operator+(const mint &lhs, const mint &rhs) { return mint(lhs.a) += rhs; }
mint operator+(const mint &lhs, const ll &rhs) { return mint(lhs.a) += rhs; }
mint operator+(const ll &lhs, const mint &rhs) { return mint(lhs) += rhs; }
mint operator-(const mint &lhs, const mint &rhs) { return mint(lhs.a) -= rhs; }
mint operator-(const mint &lhs, const ll &rhs) { return mint(lhs.a) -= rhs; }
mint operator-(const ll &lhs, const mint &rhs) { return mint(lhs) -= rhs; }
mint operator*(const mint &lhs, const mint &rhs) { return mint(lhs.a) *= rhs; }
mint operator*(const mint &lhs, const ll &rhs) { return mint(lhs.a) *= rhs; }
mint operator*(const ll &lhs, const mint &rhs) { return mint(lhs) *= rhs; }
mint operator/(const mint &lhs, const mint &rhs) { return mint(lhs.a) /= rhs; }
mint operator/(const mint &lhs, const ll &rhs) { return mint(lhs.a) /= rhs; }
mint operator/(const ll &lhs, const mint &rhs) { return mint(lhs) /= rhs; }

ll N, A, B, K;

int main() {
  cin >> N >> A >> B >> K;

  vector<mint> fact = vector<mint>(N + 1);
  fact[0] = mint(1);
  REP(i, N) { fact[i + 1] = (i + 1) * fact[i]; }
  auto comb = [&](ll n, ll r) { return fact[n] / (fact[r] * fact[n - r]); };

  mint ans = mint(0);
  REP(i, N + 1) {
    ll r = K - i * A;
    if (r >= 0 and r % B == 0 and r / B <= N) {
      ans += comb(N, i) * comb(N, r / B);
    }
  }

  OUT(ans.a);
}