Problem p03770 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#define mk make_pair
#define fi first
#define nd second
#define pii pair<int, int>
#define pb push_back
#define sqr(x) ((x) * (x))
using namespace std;
typedef long long ll;
inline ll read() {
  ll x = 0;
  char ch = getchar(), w = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      w = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * w;
}
void write(ll x) {
  if (x < 0)
    putchar('-'), x = -x;
  if (x > 9)
    write(x / 10);
  putchar(x % 10 + '0');
}
inline void writeln(ll x) {
  write(x);
  puts("");
}
const int N = 3e5;
struct T {
  int c, w;
} a[N];
int n, x, y;
ll inv[N], fac[N];
const ll p = 1e9 + 7;
ll ksm(ll x, ll y) {
  ll res = 1;
  for (; y; y >>= 1, x = x * x % p)
    if (y & 1)
      res = res * x % p;
  return res;
}
ll ans[N];
int mn[N];
int t1, t2;
int siz[N];
ll C(int n, int m) { return fac[n] * inv[m] % p * inv[n - m] % p; }
int main() {
  freopen("keep.in", "r", stdin);
  freopen("keep.out", "w", stdout);
  n = read(), x = read(), y = read();
  inv[0] = fac[0] = 1;
  for (int i = 1; i <= n; ++i) {
    fac[i] = fac[i - 1] * i % p;
    inv[i] = ksm(fac[i], p - 2);
    // inv[i] = fac[i];
    mn[i] = 1e9 + 9;
  }
  for (int i = 1; i <= n; ++i) {
    a[i].c = read(), a[i].w = read();
    mn[a[i].c] = min(mn[a[i].c], a[i].w);
  }
  for (int i = 1; i <= n; ++i) {
    if (!t1 || mn[i] < mn[t1])
      t2 = t1, t1 = i;
    else if (!t2 || mn[i] < mn[t2])
      t2 = i;
  }
  int tot = 0;
  for (int i = 1; i <= n; ++i) {
    if (a[i].w + mn[a[i].c] <= x)
      a[i].w = mn[a[i].c];
    if (a[i].c == t1) {
      if (mn[t2] + a[i].w <= y) {
        ++siz[t1];
        ++tot;
      }
    } else if (mn[t1] + a[i].w <= y) {
      //++siz[t1];
      ++siz[a[i].c];
      ++tot;
    }
  }
  ll res = 1;
  for (int i = 1; i <= n; ++i)
    if (siz[i]) {
      res = res * C(tot, siz[i]) % p;
      tot -= siz[i];
    }
  writeln(res);
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#define mk make_pair
#define fi first
#define nd second
#define pii pair<int, int>
#define pb push_back
#define sqr(x) ((x) * (x))
using namespace std;
typedef long long ll;
inline ll read() {
  ll x = 0;
  char ch = getchar(), w = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      w = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * w;
}
void write(ll x) {
  if (x < 0)
    putchar('-'), x = -x;
  if (x > 9)
    write(x / 10);
  putchar(x % 10 + '0');
}
inline void writeln(ll x) {
  write(x);
  puts("");
}
const int N = 3e5;
struct T {
  int c, w;
} a[N];
int n, x, y;
ll inv[N], fac[N];
const ll p = 1e9 + 7;
ll ksm(ll x, ll y) {
  ll res = 1;
  for (; y; y >>= 1, x = x * x % p)
    if (y & 1)
      res = res * x % p;
  return res;
}
ll ans[N];
int mn[N];
int t1, t2;
int siz[N];
ll C(int n, int m) { return fac[n] * inv[m] % p * inv[n - m] % p; }
int main() {
  n = read(), x = read(), y = read();
  inv[0] = fac[0] = 1;
  for (int i = 1; i <= n; ++i) {
    fac[i] = fac[i - 1] * i % p;
    inv[i] = ksm(fac[i], p - 2);
    // inv[i] = fac[i];
    mn[i] = 1e9 + 9;
  }
  for (int i = 1; i <= n; ++i) {
    a[i].c = read(), a[i].w = read();
    mn[a[i].c] = min(mn[a[i].c], a[i].w);
  }
  for (int i = 1; i <= n; ++i) {
    if (!t1 || mn[i] < mn[t1])
      t2 = t1, t1 = i;
    else if (!t2 || mn[i] < mn[t2])
      t2 = i;
  }
  int tot = 0;
  for (int i = 1; i <= n; ++i) {
    if (a[i].w + mn[a[i].c] <= x)
      a[i].w = mn[a[i].c];
    if (a[i].c == t1) {
      if (mn[t2] + a[i].w <= y) {
        ++siz[t1];
        ++tot;
      }
    } else if (mn[t1] + a[i].w <= y) {
      //++siz[t1];
      ++siz[a[i].c];
      ++tot;
    }
  }
  ll res = 1;
  for (int i = 1; i <= n; ++i)
    if (siz[i]) {
      res = res * C(tot, siz[i]) % p;
      tot -= siz[i];
    }
  writeln(res);
}