Problem p03332 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>

//< in.txt > out.txt
using namespace std;
// std::ios::sync_with_stdio(false);
// std::cin.tie(0);
const long long MOD = /*1e9 + 7*/ 998244353;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ll> pdl;
typedef pair<ld, ld> pdd;
typedef vector<ll> VLL;
typedef vector<VLL> VVLL;
// typedef boost::multiprecision::cpp_int bigint;

// 拡張拡張Euclidの互除法による(階乗)逆元の求め方
// O(N)
void stairs(long long N, vector<long long> &st, long long mod = 1e9 + 7) {
  st.resize(N + 1, 1);
  for (long long n = 2; n <= N; n++) {
    st[n] = (st[n - 1] * n) % mod;
  }
}

ll stair(ll N, ll mod = 1e9 + 7) {
  ll ans = 1;
  for (ll n = 2; n <= N; n++)
    ans = (ans * n) % mod;
  return ans;
}

void modinvs(long long N, vector<long long> &inv, vector<long long> &sinv,
             long long mod = 1e9 + 7) {
  inv.resize(N + 1);
  sinv.resize(N + 1);
  inv[1] = 1;
  sinv[0] = 1;
  sinv[1] = 1;
  for (int n = 2; n <= N; n++) {
    inv[n] = mod - (inv[mod % n] * (mod / n)) % mod;
    sinv[n] = (sinv[n - 1] * inv[n]) % mod;
  }
}

//(n^(-1),(n!)^(-1))
pll modinvs(ll N, ll mod = 1e9 + 7) {
  vector<ll> inv(N + 1);
  inv[1] = 1;
  ll sinv = 1;
  for (int n = 2; n <= N; n++) {
    inv[n] = mod - (inv[mod % n] * (mod / n)) % mod;
    sinv = (sinv * inv[n]) % mod;
  }
  return pll(inv[N], sinv);
}

long long Comb(long long n, long long k, vector<long long> &st,
               vector<long long> &sinv, long long mod = 1e9 + 7) {
  long long ans = st[n];
  ans = (ans * sinv[n - k]) % mod;
  ans = (ans * sinv[k]) % mod;
  return ans;
}

// ax+by=gcd(a,b)の解
ll extgcd(ll a, ll b, ll &x, ll &y) {
  ll d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}

VLL st, inv, sinv;
ll N, A, B, K;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  cin >> N >> A >> B >> K;
  stairs(N, st, 998244353);
  modinvs(N, inv, sinv, 998244353);
  ll ans = 0;
  for (ll a0 = 0; a0 <= N; a0++) {
    ll left = K - a0 * A;
    if (left % B != 0)
      continue;
    ll b0 = left / B;
    ll temp = Comb(N, a0, st, sinv, MOD);
    temp = (temp * Comb(N, b0, st, sinv, MOD)) % MOD;
    ans = (ans + temp) % MOD;
  }
  cout << ans << "\n";
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>

//< in.txt > out.txt
using namespace std;
// std::ios::sync_with_stdio(false);
// std::cin.tie(0);
const long long MOD = /*1e9 + 7*/ 998244353;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ll> pdl;
typedef pair<ld, ld> pdd;
typedef vector<ll> VLL;
typedef vector<VLL> VVLL;
// typedef boost::multiprecision::cpp_int bigint;

// 拡張拡張Euclidの互除法による(階乗)逆元の求め方
// O(N)
void stairs(long long N, vector<long long> &st, long long mod = 1e9 + 7) {
  st.resize(N + 1, 1);
  for (long long n = 2; n <= N; n++) {
    st[n] = (st[n - 1] * n) % mod;
  }
}

ll stair(ll N, ll mod = 1e9 + 7) {
  ll ans = 1;
  for (ll n = 2; n <= N; n++)
    ans = (ans * n) % mod;
  return ans;
}

void modinvs(long long N, vector<long long> &inv, vector<long long> &sinv,
             long long mod = 1e9 + 7) {
  inv.resize(N + 1);
  sinv.resize(N + 1);
  inv[1] = 1;
  sinv[0] = 1;
  sinv[1] = 1;
  for (int n = 2; n <= N; n++) {
    inv[n] = mod - (inv[mod % n] * (mod / n)) % mod;
    sinv[n] = (sinv[n - 1] * inv[n]) % mod;
  }
}

//(n^(-1),(n!)^(-1))
pll modinvs(ll N, ll mod = 1e9 + 7) {
  vector<ll> inv(N + 1);
  inv[1] = 1;
  ll sinv = 1;
  for (int n = 2; n <= N; n++) {
    inv[n] = mod - (inv[mod % n] * (mod / n)) % mod;
    sinv = (sinv * inv[n]) % mod;
  }
  return pll(inv[N], sinv);
}

long long Comb(long long n, long long k, vector<long long> &st,
               vector<long long> &sinv, long long mod = 1e9 + 7) {
  long long ans = st[n];
  ans = (ans * sinv[n - k]) % mod;
  ans = (ans * sinv[k]) % mod;
  return ans;
}

// ax+by=gcd(a,b)の解
ll extgcd(ll a, ll b, ll &x, ll &y) {
  ll d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}

VLL st, inv, sinv;
ll N, A, B, K;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  cin >> N >> A >> B >> K;
  stairs(N, st, 998244353);
  modinvs(N, inv, sinv, 998244353);
  ll ans = 0;
  for (ll a0 = 0; a0 <= N; a0++) {
    ll left = K - a0 * A;
    if (left % B != 0)
      continue;
    ll b0 = left / B;
    if (b0 < 0 || b0 > N)
      continue;
    ll temp = Comb(N, a0, st, sinv, MOD);
    temp = (temp * Comb(N, b0, st, sinv, MOD)) % MOD;
    ans = (ans + temp) % MOD;
  }
  cout << ans << "\n";
  return 0;
}