Problem p03332 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <limits>

#define pf printf
// #define DEBUG true
#define DEBUG false
#define ifd if (DEBUG)
#define FOR(i, ii, n) for (int i = ii; i < n; i++)
#define FORREV(i, ii, n) for (int i = n - 1; i >= ii; i--)
#define INF ((ll)1e15)

using namespace std;
typedef long long ll;

ll const NMAX = 3000000;
ll mod = 998244353;
ll fact[NMAX];
ll finv[NMAX];
ll comb(ll n, ll a) { return fact[n] * finv[a] % mod * finv[n - a] % mod; }
ll pow(ll a, ll n) {
  ll prd = 1;
  ll exp = a;
  while (n > 0) {
    if ((n & 1) == 1) {
      prd *= exp;
      prd %= mod;
    }
    exp *= exp;
    exp %= mod;
    n >>= 1;
  }
  return prd;
}

ll gcd(ll a, ll b) {
  if (a < b) {
    ll tmp = b;
    b = a;
    a = tmp;
  }
  ll r = a % b;
  if (r == 0)
    return b;
  return gcd(b, r);
}
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }

int main() {
  ll N, A, B, K;
  cin >> N >> A >> B >> K;
  // init
  fact[0] = 1;
  finv[0] = 1;
  FOR(i, 1, N + 1) {
    fact[i] = fact[i - 1] * i % mod;
    finv[i] = pow(fact[i], mod - 2);
  }
  FOR(i, 0, 10) {
    // ifd pf("fact[%d]=%lld\n",i,fact[i]);
    // ifd pf("finv[%d]=%lld\n",i,finv[i]);
  }
  ll cnt = 0;
  ll lcm_ = lcm(A, B);
  FOR(i, 0, B) {
    ll r = K - A * i;
    ifd if (i % 100 == 0) pf("r = %lld\n", r);
    if (r < 0)
      break;
    if (r % B == 0) {
      ifd pf("one solution found : a = %lld, b = %lld\n", i, r / B);
      // found a solution
      int j = i;
      while (K - A * j >= 0 && j <= N) {
        // ifd pf("solution found : A, a = %lld, %lld, B, b = %lld, %lld, K =
        // %lld\n", A, a, B, b, K);
        cnt += comb(N, j) * comb(N, (K - A * j) / B) % mod;
        cnt %= mod;
        j += lcm_ / A;
      }
      break;
    }
  }
  cout << cnt;
}


Fixed submission:
#include <iostream>
#include <limits>

#define pf printf
// #define DEBUG true
#define DEBUG false
#define ifd if (DEBUG)
#define FOR(i, ii, n) for (int i = ii; i < n; i++)
#define FORREV(i, ii, n) for (int i = n - 1; i >= ii; i--)
#define INF ((ll)1e15)

using namespace std;
typedef long long ll;

ll const NMAX = 3000000;
ll mod = 998244353;
ll fact[NMAX];
ll finv[NMAX];
ll comb(ll n, ll a) { return fact[n] * finv[a] % mod * finv[n - a] % mod; }
ll pow(ll a, ll n) {
  ll prd = 1;
  ll exp = a;
  while (n > 0) {
    if ((n & 1) == 1) {
      prd *= exp;
      prd %= mod;
    }
    exp *= exp;
    exp %= mod;
    n >>= 1;
  }
  return prd;
}

ll gcd(ll a, ll b) {
  if (a < b) {
    ll tmp = b;
    b = a;
    a = tmp;
  }
  ll r = a % b;
  if (r == 0)
    return b;
  return gcd(b, r);
}
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }

int main() {
  ll N, A, B, K;
  cin >> N >> A >> B >> K;
  // init
  fact[0] = 1;
  finv[0] = 1;
  FOR(i, 1, N + 1) {
    fact[i] = fact[i - 1] * i % mod;
    finv[i] = pow(fact[i], mod - 2);
  }
  FOR(i, 0, 10) {
    // ifd pf("fact[%d]=%lld\n",i,fact[i]);
    // ifd pf("finv[%d]=%lld\n",i,finv[i]);
  }
  ll cnt = 0;
  ll lcm_ = lcm(A, B);
  FOR(i, 0, B) {
    ll r = K - A * i;
    ifd if (i % 100 == 0) pf("r = %lld\n", r);
    if (r < 0)
      break;
    if (r % B == 0) {
      ifd pf("one solution found : a = %lld, b = %lld\n", i, r / B);
      // found a solution
      int j = i;
      while (K - A * j >= 0 && j <= N) {
        // ifd pf("solution found : A, a = %lld, %lld, B, b = %lld, %lld, K =
        // %lld\n", A, a, B, b, K);
        ll b = (K - A * j) / B;
        if (b <= N) {
          cnt += comb(N, j) * comb(N, b) % mod;
          cnt %= mod;
        }
        j += lcm_ / A;
      }
      break;
    }
  }
  cout << cnt;
}