Problem p03184 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;
using i64 = int64_t;
using i32 = int32_t;
template <class T, class U> void init_n(vector<T> &v, size_t n, U x) {
  v = vector<T>(n, x);
}
template <class T> void init_n(vector<T> &v, size_t n) { init_n(v, n, T()); }
template <class T> void read_n(vector<T> &v, size_t n, size_t o = 0) {
  v = vector<T>(n + o);
  for (size_t i = o; i < n + o; ++i)
    cin >> v[i];
}
template <class T> void read_n(T a[], size_t n, size_t o = 0) {
  for (size_t i = o; i < n + o; ++i)
    cin >> a[i];
}
template <class T> T gabs(const T &x) { return max(x, -x); }
#define abs gabs

const i64 mod = 1e9 + 7;
i64 fact_memo[200001];
i64 fact(i64 x) {
  if (x == 0)
    return 1;
  if (fact_memo[x])
    return fact_memo[x];
  return fact_memo[x] = x * fact(x - 1) % mod;
}
i64 ipow(i64 a, i64 b) {
  return (b & 1 ? a : 1) * (b > 1 ? ipow(a * a % mod, b >> 1) : 1) % mod;
}
i64 inv(i64 x) { return ipow(x, mod - 2); }
i64 fact_inv(i64 x) { return inv(fact(x)); }
i64 perm(i64 a, i64 b) { return fact(a) * fact_inv(a - b) % mod; }
i64 conb(i64 a, i64 b) {
  return fact(a) * fact_inv(b) % mod * fact_inv(a - b) % mod;
}

i64 h, w, n;
using P = pair<i64, i64>;
vector<P> ps;
int main() {
  cin >> h >> w >> n;
  init_n(ps, n + 1);
  for (i64 i = 0; i < n; ++i) {
    cin >> ps[i].first >> ps[i].second;
  }
  ps[n] = {h, w};
  sort(begin(ps), end(ps));

  vector<i64> dp(n + 1);
  for (i64 i = 0; i <= n; ++i) {
    i64 r, c;
    tie(r, c) = ps[i];
    dp[i] = conb(r + c - 2, r - 1);
    for (i64 j = 0; j < i; ++j) {
      i64 r2, c2;
      tie(r2, c2) = ps[j];
      if (r2 <= r && c2 <= c) {
        dp[i] += mod - dp[j] * conb(r - r2 + c - c2, c - c2) % mod;
      }
    }
    dp[i] %= mod;
    // fprintf(stderr, "%lld: (%lld, %lld)\t%lld\n", i, r, c, dp[i]);
  }
  cout << dp[n] << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;
using i64 = int64_t;
using i32 = int32_t;
template <class T, class U> void init_n(vector<T> &v, size_t n, U x) {
  v = vector<T>(n, x);
}
template <class T> void init_n(vector<T> &v, size_t n) { init_n(v, n, T()); }
template <class T> void read_n(vector<T> &v, size_t n, size_t o = 0) {
  v = vector<T>(n + o);
  for (size_t i = o; i < n + o; ++i)
    cin >> v[i];
}
template <class T> void read_n(T a[], size_t n, size_t o = 0) {
  for (size_t i = o; i < n + o; ++i)
    cin >> a[i];
}
template <class T> T gabs(const T &x) { return max(x, -x); }
#define abs gabs

const i64 mod = 1e9 + 7;
i64 fact_memo[200001];
i64 fact(i64 x) {
  if (x == 0)
    return 1;
  if (fact_memo[x])
    return fact_memo[x];
  return fact_memo[x] = x * fact(x - 1) % mod;
}
i64 ipow(i64 a, i64 b) {
  return (b & 1 ? a : 1) * (b > 1 ? ipow(a * a % mod, b >> 1) : 1) % mod;
}
i64 inv(i64 x) { return ipow(x, mod - 2); }
i64 fact_inv_memo[200001];
i64 fact_inv(i64 x) {
  if (fact_inv_memo[x])
    return fact_inv_memo[x];
  return fact_inv_memo[x] = inv(fact(x));
}
i64 perm(i64 a, i64 b) { return fact(a) * fact_inv(a - b) % mod; }
i64 conb(i64 a, i64 b) {
  return fact(a) * fact_inv(b) % mod * fact_inv(a - b) % mod;
}

i64 h, w, n;
using P = pair<i64, i64>;
vector<P> ps;
int main() {
  cin >> h >> w >> n;
  init_n(ps, n + 1);
  for (i64 i = 0; i < n; ++i) {
    cin >> ps[i].first >> ps[i].second;
  }
  ps[n] = {h, w};
  sort(begin(ps), end(ps));

  vector<i64> dp(n + 1);
  for (i64 i = 0; i <= n; ++i) {
    i64 r, c;
    tie(r, c) = ps[i];
    dp[i] = conb(r + c - 2, r - 1);
    for (i64 j = 0; j < i; ++j) {
      i64 r2, c2;
      tie(r2, c2) = ps[j];
      if (r2 <= r && c2 <= c) {
        dp[i] += mod - dp[j] * conb(r - r2 + c - c2, c - c2) % mod;
      }
    }
    dp[i] %= mod;
    // fprintf(stderr, "%lld: (%lld, %lld)\t%lld\n", i, r, c, dp[i]);
  }
  cout << dp[n] << endl;
  return 0;
}