Problem p03770 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
const ll MOD = 1e9 + 7;
ll powmod(ll a, ll k) {
  ll ap = a, ans = 1;
  while (k) {
    if (k & 1) {
      ans *= ap;
      ans %= MOD;
    }
    ap = ap * ap;
    ap %= MOD;
    k >>= 1;
  }
  return ans;
}
ll inv(ll a) { return powmod(a, MOD - 2); }
ll f[200001];
ll invf[200001];
void fac(int n) {
  f[0] = 1;
  for (ll i = 1; i <= n; i++)
    f[i] = f[i - 1] * i % MOD;
  invf[n] = inv(f[n]);
  for (ll i = n - 1; i >= 0; i--)
    invf[i] = invf[i + 1] * (i + 1) % MOD;
}

int main() {
  int n, x, y;
  cin >> n >> x >> y;
  fac(n);
  vector<int> w[200001];
  for (int i = 0; i < n; i++) {
    int c, w1;
    cin >> c >> w1;
    c--;
    w[c].push_back(w1);
  }
  int i0 = -1, i1 = -1;
  for (int i = 0; i < n; i++) {
    sort(w[i].begin(), w[i].end());
    if (!w[i].empty()) {
      if (i0 == -1 || w[i0][0] > w[i][0]) {
        i1 = i0;
        i0 = i;
      } else if (i1 == -1 || w[i1][0] > w[i][0]) {
        i1 = i;
      }
    }
  }
  int s = 0, ct[200001];
  for (int i = 0; i < n; i++) {
    if (w[i].empty() || w[i][0] + w[i0][0] > y) {
      ct[i] = 0;
      continue;
    }
    if (i == i0)
      ct[i] = max((int)(upper_bound(w[i].begin(), w[i].end(), x - w[i][0]) -
                        w[i].begin()),
                  (int)(upper_bound(w[i].begin(), w[i].end(), y - w[i1][0]) -
                        w[i].begin()));
    else
      ct[i] = max((int)(upper_bound(w[i].begin(), w[i].end(), x - w[i][0]) -
                        w[i].begin()),
                  (int)(upper_bound(w[i].begin(), w[i].end(), y - w[i0][0]) -
                        w[i].begin()));
    s += ct[i];
  }
  ll ans = f[s];
  for (int i = 0; i < n; i++) {
    // cout<<ct[i]<<endl;
    ans *= invf[ct[i]];
    ans %= MOD;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
const ll MOD = 1e9 + 7;
ll powmod(ll a, ll k) {
  ll ap = a, ans = 1;
  while (k) {
    if (k & 1) {
      ans *= ap;
      ans %= MOD;
    }
    ap = ap * ap;
    ap %= MOD;
    k >>= 1;
  }
  return ans;
}
ll inv(ll a) { return powmod(a, MOD - 2); }
ll f[200001];
ll invf[200001];
void fac(int n) {
  f[0] = 1;
  for (ll i = 1; i <= n; i++)
    f[i] = f[i - 1] * i % MOD;
  invf[n] = inv(f[n]);
  for (ll i = n - 1; i >= 0; i--)
    invf[i] = invf[i + 1] * (i + 1) % MOD;
}

int main() {
  int n, x, y;
  cin >> n >> x >> y;
  fac(n);
  vector<int> w[200001];
  for (int i = 0; i < n; i++) {
    int c, w1;
    cin >> c >> w1;
    c--;
    w[c].push_back(w1);
  }
  int i0 = -1, i1 = -1;
  for (int i = 0; i < n; i++) {
    sort(w[i].begin(), w[i].end());
    if (!w[i].empty()) {
      if (i0 == -1 || w[i0][0] > w[i][0]) {
        i1 = i0;
        i0 = i;
      } else if (i1 == -1 || w[i1][0] > w[i][0]) {
        i1 = i;
      }
    }
  }
  int s = 0, ct[200001];
  for (int i = 0; i < n; i++) {
    if (w[i].empty() || w[i][0] + w[i0][0] > y) {
      ct[i] = 0;
      continue;
    }
    ct[i] = (int)(upper_bound(w[i].begin(), w[i].end(), x - w[i][0]) -
                  w[i].begin());
    if (i == i0) {
      if (i1 != -1)
        ct[i] = max(ct[i],
                    (int)(upper_bound(w[i].begin(), w[i].end(), y - w[i1][0]) -
                          w[i].begin()));
    } else {
      ct[i] =
          max(ct[i], (int)(upper_bound(w[i].begin(), w[i].end(), y - w[i0][0]) -
                           w[i].begin()));
    }
    s += ct[i];
  }
  ll ans = f[s];
  for (int i = 0; i < n; i++) {
    // cout<<ct[i]<<endl;
    ans *= invf[ct[i]];
    ans %= MOD;
  }
  cout << ans << endl;
  return 0;
}