Problem p03027 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
//~ #define MOD 1000000007
#define MOD 1000003
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

ll ppow(ll a, ll b) {
  a %= MOD;
  ll res = 1;
  while (b) {
    if (b & 1)
      res = (res * a) % MOD;
    a = (a * a) % MOD;
    b >>= 1;
  }
  return res;
}
class Fact {
  vector<ll> fact;
  vector<ll> inv;

public:
  Fact() {}
  Fact(int n) {
    n = n * 2 + 10;
    fact = inv = vector<ll>(n);
    fact[0] = inv[0] = 1;
    for (int i = 1; i < n; i++) {
      fact[i] = (fact[i - 1] * i) % MOD;
      inv[i] = ppow(fact[i], MOD - 2);
    }
  }
  ll get(int n) { return fact[n]; }
  ll nPr(int n, int r) { return fact[n] * inv[n - r] % MOD; }
  ll nCr(int n, int r) { return nPr(n, r) * inv[r] % MOD; }
  ll nrP(int n, int r) { return nPr(n + r, n); }
  ll nrC(int n, int r) { return nCr(n + r, n); }
};

// 負の数にも対応した mod
// 例えば -17 を 5 で割った余りは本当は 3 (-17 ≡ 3 (mod. 5))
// しかし単に -17 % 5 では -2 になってしまう
inline long long mod(long long a, long long m) { return (a % m + m) % m; }

// 拡張 Euclid の互除法
// ap + bq = gcd(a, b) となる (p, q) を求め、d = gcd(a, b) をリターンします
long long extGcd(long long a, long long b, long long &p, long long &q) {
  if (b == 0) {
    p = 1;
    q = 0;
    return a;
  }
  long long d = extGcd(b, a % b, q, p);
  q -= a / b * p;
  return d;
}

// 中国剰余定理
// リターン値を (r, m) とすると解は x ≡ r (mod. m)
// 解なしの場合は (0, -1) をリターン
pair<long long, long long> ChineseRem(long long b1, long long m1, long long b2,
                                      long long m2) {
  long long p, q;
  long long d = extGcd(m1, m2, p, q); // p is inv of m1/d (mod. m2/d)
  if ((b2 - b1) % d != 0)
    return make_pair(0, -1);
  long long m = m1 * (m2 / d); // lcm of (m1, m2)
  long long tmp = (b2 - b1) / d * p % (m2 / d);
  long long r = mod(b1 + m1 * tmp, m);
  return make_pair(r, m);
}

int main() {
  Fact fac(1000000);
  int q;
  cin >> q;
  rep(i, q) {
    ll x, d, n;
    scanf("%lld%lld%lld", &x, &d, &n);
    if (x == 0) {
      puts("0");
      continue;
    }
    if (d == 0) {
      printf("%lld\n", ppow(x, n));
      continue;
    }
    auto p = ChineseRem(x % d, d, 0, MOD);
    ll a = (x + p.first - 1) / p.first * p.first;
    if ((a - x) / d < n) {
      puts("0");
      continue;
    }
    ll ans =
        ppow(d, n) * fac.get((x * ppow(d, MOD - 2) + n + MOD - 1) % MOD) % MOD *
        ppow(fac.get((x * ppow(d, MOD - 2) + MOD - 1) % MOD), MOD - 2) % MOD;
    printf("%lld\n", ans);
  }
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
//~ #define MOD 1000000007
#define MOD 1000003
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

ll ppow(ll a, ll b) {
  a %= MOD;
  ll res = 1;
  while (b) {
    if (b & 1)
      res = (res * a) % MOD;
    a = (a * a) % MOD;
    b >>= 1;
  }
  return res;
}
class Fact {
  vector<ll> fact;
  vector<ll> inv;

public:
  Fact() {}
  Fact(int n) {
    n = n * 2 + 10;
    fact = inv = vector<ll>(n);
    fact[0] = inv[0] = 1;
    for (int i = 1; i < n; i++) {
      fact[i] = (fact[i - 1] * i) % MOD;
      inv[i] = ppow(fact[i], MOD - 2);
    }
  }
  ll get(int n) { return fact[n]; }
  ll nPr(int n, int r) { return fact[n] * inv[n - r] % MOD; }
  ll nCr(int n, int r) { return nPr(n, r) * inv[r] % MOD; }
  ll nrP(int n, int r) { return nPr(n + r, n); }
  ll nrC(int n, int r) { return nCr(n + r, n); }
};

// 負の数にも対応した mod
// 例えば -17 を 5 で割った余りは本当は 3 (-17 ≡ 3 (mod. 5))
// しかし単に -17 % 5 では -2 になってしまう
inline long long mod(long long a, long long m) { return (a % m + m) % m; }

// 拡張 Euclid の互除法
// ap + bq = gcd(a, b) となる (p, q) を求め、d = gcd(a, b) をリターンします
long long extGcd(long long a, long long b, long long &p, long long &q) {
  if (b == 0) {
    p = 1;
    q = 0;
    return a;
  }
  long long d = extGcd(b, a % b, q, p);
  q -= a / b * p;
  return d;
}

// 中国剰余定理
// リターン値を (r, m) とすると解は x ≡ r (mod. m)
// 解なしの場合は (0, -1) をリターン
pair<long long, long long> ChineseRem(long long b1, long long m1, long long b2,
                                      long long m2) {
  long long p, q;
  long long d = extGcd(m1, m2, p, q); // p is inv of m1/d (mod. m2/d)
  if ((b2 - b1) % d != 0)
    return make_pair(0, -1);
  long long m = m1 * (m2 / d); // lcm of (m1, m2)
  long long tmp = (b2 - b1) / d * p % (m2 / d);
  long long r = mod(b1 + m1 * tmp, m);
  return make_pair(r, m);
}

int main() {
  Fact fac(1000000);
  int q;
  cin >> q;
  rep(i, q) {
    ll x, d, n;
    scanf("%lld%lld%lld", &x, &d, &n);
    if (x == 0) {
      puts("0");
      continue;
    }
    if (d == 0) {
      printf("%lld\n", ppow(x, n));
      continue;
    }
    auto p = ChineseRem(x % d, d, 0, MOD);
    ll a = (x - p.first + p.second - 1) / p.second * p.second + p.first;
    if ((a - x) / d < n) {
      puts("0");
      continue;
    }
    ll ans =
        ppow(d, n) * fac.get((x * ppow(d, MOD - 2) + n + MOD - 1) % MOD) % MOD *
        ppow(fac.get((x * ppow(d, MOD - 2) + MOD - 1) % MOD), MOD - 2) % MOD;
    printf("%lld\n", ans);
  }
}