Problem p03184 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long ll;
typedef pair<ll, ll> mp;

/*
除DP
dp[i]=|初めて通った壁がi番目|
dp[i]=|(1,1) \to w_i| - \sum^{i-1}_{j=0}|w_j \to w_i|dp[j]
*/

struct pos {
  ll x, y;
};
bool operator<(const pos &lhs, const pos &rhs) {
  return lhs.x + lhs.y < rhs.x + rhs.y;
}

struct Factorial {
  long long N, mod;
  vector<long long> fact, inv;
  long long mod_pow(long long x, long long n) {
    long long res = 1;
    while (n) {
      if (n & 1)
        (res *= x) %= mod;
      (x *= x) %= mod;
      n >>= 1;
    }
    return res;
  }
  long long Inverse(long long n) { return mod_pow(n, mod - 2); }
  Factorial() {}
  Factorial(long long sn, long long smod) {
    N = sn;
    mod = smod;
    fact.reserve(sn + 1);
    inv.reserve(sn + 1);
    // 初期化
    fact[0] = 1;
    for (int i = 1; i <= sn; i++) {
      fact[i] = (fact[i - 1] * i) % mod;
    }
    inv[sn] = Inverse(fact[sn]);
    for (int i = sn; i > 0; i--) {
      inv[i - 1] = (inv[i] * i) % mod;
    }
  }
  long long Fact(long long n) {
    if (n < 0)
      return 0;
    return fact[n];
  }
  long long Inv(long long n) {
    if (n < 0)
      return 0;
    return inv[n];
  }
  long long Combination(long long n, long long r) {
    if (n < r)
      return 0;
    if (r < 0)
      return 0;
    if (r == 0)
      return 1;
    long long ans = 1;
    ans = (ans * Fact(n)) % mod;
    ans = (ans * Inv(r)) % mod;
    ans = (ans * Inv(n - r)) % mod;
    return ans;
  }
};

ll H, W, n, dp[2010] = {}, ans = 0, mod = 1e9 + 7;
pos w[3010];

int main(void) {
  cin >> H >> W >> n;
  rep(i, n) {
    ll x, y;
    cin >> y >> x;
    w[i] = {x, y};
  }
  w[n] = {W, H};
  //
  Factorial f(200010, mod);
  sort(w, w + n + 1);
  reg(i, 0, n) {
    ll sum = 0;
    rep(j, i) {
      if (w[i].x >= w[j].x && w[i].y >= w[j].y) {
        sum = (sum + (dp[j] * f.Combination(w[i].x - w[j].x + w[i].y - w[j].y,
                                            w[i].x - w[j].x)) %
                         mod) %
              mod;
      }
    }
    dp[i] = (f.Combination(w[i].x + w[i].y - 2, w[i].x - 1) + mod - sum) % mod;
  }
  cout << dp[n] << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long ll;
typedef pair<ll, ll> mp;

/*
除DP
dp[i]=|初めて通った壁がi番目|
dp[i]=|(1,1) \to w_i| - \sum^{i-1}_{j=0}|w_j \to w_i|dp[j]
*/

struct pos {
  ll x, y;
};
bool operator<(const pos &lhs, const pos &rhs) {
  return lhs.x + lhs.y < rhs.x + rhs.y;
}

struct Factorial {
  long long N, mod;
  vector<long long> fact, inv;
  long long mod_pow(long long x, long long n) {
    long long res = 1;
    while (n) {
      if (n & 1)
        (res *= x) %= mod;
      (x *= x) %= mod;
      n >>= 1;
    }
    return res;
  }
  long long Inverse(long long n) { return mod_pow(n, mod - 2); }
  Factorial() {}
  Factorial(long long sn, long long smod) {
    N = sn;
    mod = smod;
    fact.reserve(sn + 1);
    inv.reserve(sn + 1);
    // 初期化
    fact[0] = 1;
    for (int i = 1; i <= sn; i++) {
      fact[i] = (fact[i - 1] * i) % mod;
    }
    inv[sn] = Inverse(fact[sn]);
    for (int i = sn; i > 0; i--) {
      inv[i - 1] = (inv[i] * i) % mod;
    }
  }
  long long Fact(long long n) {
    if (n < 0)
      return 0;
    return fact[n];
  }
  long long Inv(long long n) {
    if (n < 0)
      return 0;
    return inv[n];
  }
  long long Combination(long long n, long long r) {
    if (n < r)
      return 0;
    if (r < 0)
      return 0;
    if (r == 0)
      return 1;
    long long ans = 1;
    ans = (ans * Fact(n)) % mod;
    ans = (ans * Inv(r)) % mod;
    ans = (ans * Inv(n - r)) % mod;
    return ans;
  }
};

ll H, W, n, dp[3010] = {}, ans = 0, mod = 1e9 + 7;
pos w[3010];

int main(void) {
  cin >> H >> W >> n;
  rep(i, n) {
    ll x, y;
    cin >> y >> x;
    w[i] = {x, y};
  }
  w[n] = {W, H};
  //
  Factorial f(200010, mod);
  sort(w, w + n + 1);
  reg(i, 0, n) {
    ll sum = 0;
    rep(j, i) {
      if (w[i].x >= w[j].x && w[i].y >= w[j].y) {
        sum = (sum + (dp[j] * f.Combination(w[i].x - w[j].x + w[i].y - w[j].y,
                                            w[i].x - w[j].x)) %
                         mod) %
              mod;
      }
    }
    dp[i] = (f.Combination(w[i].x + w[i].y - 2, w[i].x - 1) + mod - sum) % mod;
  }
  cout << dp[n] << endl;
  return 0;
}