Problem p04046 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
// #include <ext/numeric>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define oo 0x3f3f3f3f
#define OO 0x3f3f3f3f3f3f3f3f
#define popcount(n) __builtin_popcount(n)
#define popcountll(n) __builtin_popcountll(n)

using namespace std;
// using namespace __gnu_cxx;
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef pair<long long, int> ii;
typedef pair<long long, pair<int, int>> iii;
typedef pair<ii, ii> iiii;

const double PI = acos(-1.0), EPS = 1e-6;
const long long inf = 2e12 + 12;
const int MAXN = 200005, MAXM = 100005, Mod = 1000000007, MAXLog = 20;

int Fact[MAXN], FactInv[MAXN];

int mul(int x, int y) { return 1LL * x * y % Mod; }

int add(int x, int y) { return (0LL + x + y) % Mod; }

int power(int b, int e, int mod) {
  if (e == 0)
    return 1;
  int x = power(b, e >> 1, mod);
  x = 1LL * x * x % mod;
  if (e & 1)
    x = 1LL * x * b % mod;

  return x;
}

int nCr(int n, int r) {
  if (n < r)
    return 0;
  return mul(Fact[n], mul(FactInv[r], FactInv[n - r]));
}

void pre(int H, int W) {
  Fact[0] = 1;
  FactInv[0] = 1;
  for (int i = 1; i <= H + W; ++i) {
    Fact[i] = mul(Fact[i - 1], i);
    FactInv[i] = power(Fact[i], Mod - 2, Mod);
  }
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "rt", stdin);
//    freopen("output.txt", "w", stdout);
#endif
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0), cout.precision(10),
      cout << fixed;

  int H, W, A, B;
  cin >> H >> W >> A >> B;
  pre(H, W);
  int X = H - A;
  int Y = W - B;
  int ans = 0;
  for (int i = 0; i < X; ++i) {
    ans = add(ans, mul(nCr(i + B - 1, i), nCr(H - i + Y - 2, H - 1 - i)));
  }

  cout << ans << '\n';

  // X = H - A + 1
  // Y = W - B + 1
  // sum from i = 0 to i = X - 1
  // i + 1 + B - 2 C i * H - 1 - i + Y C H - i - 1

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
// #include <ext/numeric>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define oo 0x3f3f3f3f
#define OO 0x3f3f3f3f3f3f3f3f
#define popcount(n) __builtin_popcount(n)
#define popcountll(n) __builtin_popcountll(n)

using namespace std;
// using namespace __gnu_cxx;
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef pair<long long, int> ii;
typedef pair<long long, pair<int, int>> iii;
typedef pair<ii, ii> iiii;

const double PI = acos(-1.0), EPS = 1e-6;
const long long inf = 2e12 + 12;
const int MAXN = 200005, MAXM = 100005, Mod = 1000000007, MAXLog = 20;

int Fact[MAXN], FactInv[MAXN];

int mul(int x, int y) { return 1LL * x * y % Mod; }

int add(int x, int y) { return (0LL + x + y) % Mod; }

int power(int b, int e, int mod) {
  if (e == 0)
    return 1;
  int x = power(b, e >> 1, mod);
  x = 1LL * x * x % mod;
  if (e & 1)
    x = 1LL * x * b % mod;

  return x;
}

int nCr(int n, int r) {
  if (n < r)
    return 0;
  return mul(Fact[n], mul(FactInv[r], FactInv[n - r]));
}

void pre(int H, int W) {
  Fact[0] = 1;
  FactInv[0] = 1;
  for (int i = 1; i <= H + W; ++i) {
    Fact[i] = mul(Fact[i - 1], i);
    FactInv[i] = power(Fact[i], Mod - 2, Mod);
  }
}

int main() {
#ifndef ONLINE_JUDGE
//    freopen("input.txt", "rt", stdin);
//    freopen("output.txt", "w", stdout);
#endif
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0), cout.precision(10),
      cout << fixed;

  int H, W, A, B;
  cin >> H >> W >> A >> B;
  pre(H, W);
  int X = H - A;
  int Y = W - B;
  int ans = 0;
  for (int i = 0; i < X; ++i) {
    ans = add(ans, mul(nCr(i + B - 1, i), nCr(H - i + Y - 2, H - 1 - i)));
  }

  cout << ans << '\n';

  // X = H - A + 1
  // Y = W - B + 1
  // sum from i = 0 to i = X - 1
  // i + 1 + B - 2 C i * H - 1 - i + Y C H - i - 1

  return 0;
}