Problem p03184 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"
using namespace std;
#define FOR(i, j, k) for (int(i) = (j); (i) < (int)(k); ++(i))
#define rep(i, j) FOR(i, 0, j)
#define each(x, y) for (auto &(x) : (y))
#define mp make_pair
#define MT make_tuple
#define all(x) (x).begin(), (x).end()
#define debug(x) cout << #x << ": " << (x) << endl
#define smax(x, y) (x) = max((x), (y))
#define smin(x, y) (x) = min((x), (y))
#define MEM(x, y) memset((x), (y), sizeof(x))
#define sz(x) (int)(x).size()
#define RT return
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;

template <int MOD> class ModInt {
public:
  ModInt() : value(0) {}
  ModInt(long long val) : value((int)(val < 0 ? MOD + val % MOD : val % MOD)) {}

  ModInt &operator+=(ModInt that) {
    value = value + that.value;
    if (value >= MOD)
      value -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    value -= that.value;
    if (value < 0)
      value += MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    value = (int)((long long)value * that.value % MOD);
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
  ModInt pow(long long k) const {
    ModInt n = *this, res = 1;
    while (k) {
      if (k & 1)
        res *= n;
      n *= n;
      k >>= 1;
    }
    return res;
  }
  ModInt inverse() const {
    long long a = value, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    return ModInt(u);
  }
  int toi() const { return value; }

private:
  int value;
};
typedef ModInt<1000000007> mint;
ostream &operator<<(ostream &os, const mint &x) {
  os << x.toi();
  return os;
}

template <class S, class T>
void psort(vector<S> &u, vector<T> &v, bool isGreater = false) {
  int n = (int)u.size();
  vector<pair<S, T>> vecP(n);
  for (int i = 0; i < n; ++i) {
    vecP[i].first = u[i];
    vecP[i].second = v[i];
  }
  if (isGreater) {
    sort(vecP.rbegin(), vecP.rend());
  } else {
    sort(vecP.begin(), vecP.end());
  }
  for (int i = 0; i < n; ++i) {
    u[i] = vecP[i].first;
    v[i] = vecP[i].second;
  }
}

namespace comb {
const int N = 200005;
mint fact[N];
mint rev[N];

void init() {
  fact[0] = 1;
  for (int i = 1; i < N; ++i)
    fact[i] = fact[i - 1] * i;
  for (int i = 0; i < N; ++i)
    rev[i] = fact[i].inverse();
}

mint C(int n, int r) {
  if (n < r)
    return 0;
  return fact[n] * rev[r] * rev[n - r];
}

mint H(int n, int r) { return C(n + r - 1, r); }

mint P(int n, int r) {
  assert(n >= r);
  return fact[n] * rev[n - r];
}

mint catalan(int n) { return fact[2 * n] * rev[n + 1] * rev[n]; }
} // namespace comb

void solve() {
  comb::init();

  int H, W, N;
  cin >> H >> W >> N;
  vi R(N + 2), C(N + 2);
  rep(i, N) { cin >> R[i + 1] >> C[i + 1]; }

  R[0] = C[0] = 1;
  R[N + 1] = H;
  C[N + 1] = W;

  psort(R, C);

  static mint dp[1003][2];
  dp[0][1] = 1;

  rep(i, N + 1) {
    for (int j = i + 1; j <= N + 1; ++j) {
      int h = R[j] - R[i];
      int w = C[j] - C[i];
      if (h >= 0 && w >= 0) {
        rep(k, 2) { dp[j][k ^ 1] += dp[i][k] * comb::C(h + w, h); }
      }
    }
  }

  mint ans = dp[N + 1][0] - dp[N + 1][1];
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(15);
  solve();
  return 0;
}

Fixed submission:
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"
using namespace std;
#define FOR(i, j, k) for (int(i) = (j); (i) < (int)(k); ++(i))
#define rep(i, j) FOR(i, 0, j)
#define each(x, y) for (auto &(x) : (y))
#define mp make_pair
#define MT make_tuple
#define all(x) (x).begin(), (x).end()
#define debug(x) cout << #x << ": " << (x) << endl
#define smax(x, y) (x) = max((x), (y))
#define smin(x, y) (x) = min((x), (y))
#define MEM(x, y) memset((x), (y), sizeof(x))
#define sz(x) (int)(x).size()
#define RT return
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;

template <int MOD> class ModInt {
public:
  ModInt() : value(0) {}
  ModInt(long long val) : value((int)(val < 0 ? MOD + val % MOD : val % MOD)) {}

  ModInt &operator+=(ModInt that) {
    value = value + that.value;
    if (value >= MOD)
      value -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    value -= that.value;
    if (value < 0)
      value += MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    value = (int)((long long)value * that.value % MOD);
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
  ModInt pow(long long k) const {
    ModInt n = *this, res = 1;
    while (k) {
      if (k & 1)
        res *= n;
      n *= n;
      k >>= 1;
    }
    return res;
  }
  ModInt inverse() const {
    long long a = value, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    return ModInt(u);
  }
  int toi() const { return value; }

private:
  int value;
};
typedef ModInt<1000000007> mint;
ostream &operator<<(ostream &os, const mint &x) {
  os << x.toi();
  return os;
}

template <class S, class T>
void psort(vector<S> &u, vector<T> &v, bool isGreater = false) {
  int n = (int)u.size();
  vector<pair<S, T>> vecP(n);
  for (int i = 0; i < n; ++i) {
    vecP[i].first = u[i];
    vecP[i].second = v[i];
  }
  if (isGreater) {
    sort(vecP.rbegin(), vecP.rend());
  } else {
    sort(vecP.begin(), vecP.end());
  }
  for (int i = 0; i < n; ++i) {
    u[i] = vecP[i].first;
    v[i] = vecP[i].second;
  }
}

namespace comb {
const int N = 200005;
mint fact[N];
mint rev[N];

void init() {
  fact[0] = 1;
  for (int i = 1; i < N; ++i)
    fact[i] = fact[i - 1] * i;
  for (int i = 0; i < N; ++i)
    rev[i] = fact[i].inverse();
}

mint C(int n, int r) {
  if (n < r)
    return 0;
  return fact[n] * rev[r] * rev[n - r];
}

mint H(int n, int r) { return C(n + r - 1, r); }

mint P(int n, int r) {
  assert(n >= r);
  return fact[n] * rev[n - r];
}

mint catalan(int n) { return fact[2 * n] * rev[n + 1] * rev[n]; }
} // namespace comb

void solve() {
  comb::init();

  int H, W, N;
  cin >> H >> W >> N;
  vi R(N + 2), C(N + 2);
  rep(i, N) { cin >> R[i + 1] >> C[i + 1]; }

  R[0] = C[0] = 1;
  R[N + 1] = H;
  C[N + 1] = W;

  psort(R, C);

  static mint dp[3003][2];
  dp[0][1] = 1;

  rep(i, N + 1) {
    for (int j = i + 1; j <= N + 1; ++j) {
      int h = R[j] - R[i];
      int w = C[j] - C[i];
      if (h >= 0 && w >= 0) {
        rep(k, 2) { dp[j][k ^ 1] += dp[i][k] * comb::C(h + w, h); }
      }
    }
  }

  mint ans = dp[N + 1][0] - dp[N + 1][1];
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(15);
  solve();
  return 0;
}