Problem p03770 (C++)

Buggy submission (status: Time Limit Exceeded):
/*
{
######################
#       Author       #
#        Gary        #
#        2020        #
######################
*/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define rb(a, b, c) for (int a = b; a <= c; ++a)
#define rl(a, b, c) for (int a = b; a >= c; --a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a, b) make_pair(a, b)
#define FIR first
#define SEC second
#define FREO freopen("check.out", "w", stdout)
#define rep(a, b) for (int a = 0; a < b; ++a)
#define SRAND                                                                  \
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng() % a
#define ALL(a) a.begin(), a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin >> a
#define R2(a, b) cin >> a >> b
#define check_min(a, b) a = min(a, b)
#define check_max(a, b) a = max(a, b)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> mp;
/*}
 */
const int MOD = 1e9 + 7;
LL fact[200000 + 20], rfact[200000 + 20];
LL quick(LL A, LL B) {
  if (B == 0)
    return 1;
  LL tmp = quick(A, B >> 1);
  tmp *= tmp;
  tmp %= MOD;
  if (B & 1)
    tmp *= A, tmp %= MOD;
  return tmp;
}
LL c(int A, int B) { return fact[A] * rfact[B] % MOD * rfact[A - B] % MOD; }
vector<int> have[200000 + 20];
int fa[200000 + 20];
int root(int u) { return fa[u] = (fa[u] == u ? u : root(fa[u])); }
void merge(int u, int v) {
  if (root(u) != root(v)) {
    u = root(u);
    v = root(v);
    if (have[u] > have[v]) {
      fa[v] = u;
      for (auto it : have[v])
        have[u].PB(it);
      have[v].clear();
    } else {
      fa[u] = v;
      for (auto it : have[u])
        have[v].PB(it);
      have[u].clear();
    }
  }
}
vector<int> col[200000 + 20];
int w[200000 + 20];
bool cmp(int A, int B) { return w[A] < w[B]; }
vector<int> dsu[200000 + 20];
int main() {
  fastio;
  fact[0] = 1ll;
  int n;
  int x, y;
  R(n);
  cin >> x >> y;
  rb(i, 1, 200000) fact[i] = fact[i - 1] * i % MOD;
  rfact[200000] = quick(fact[200000], MOD - 2);
  rl(i, 200000 - 1, 1) rfact[i] = rfact[i + 1] * (i + 1) % MOD;
  rfact[0] = 1;
  rb(i, 1, n) {
    int c;
    R2(c, w[i]);
    col[c].PB(i);
    have[i].PB(c);
    fa[i] = i;
  }
  rb(i, 1, n) sort(ALL(col[i]), cmp);
  priority_queue<mp, vector<mp>, greater<mp>> heap;
  rb(i, 1, n) {
    for (auto it : col[i]) {
      if (w[it] + w[col[i][0]] <= x) {
        merge(it, col[i][0]);
      }
    }
  } // 连同色边
  rb(i, 1, n) if (root(i) == i) {
    dsu[have[i][0]].PB(i);
    heap.push(II(w[col[have[i][0]][0]], have[i][0]));
  }
  rb(i, 1, n) {
    vector<int> ban;
    while (!heap.empty() && heap.top().SEC == i)
      ban.PB(heap.top().FIR), heap.pop();
    if (!heap.empty())
      for (auto it : dsu[i]) {
        if (w[it] + heap.top().FIR <= y) {
          merge(it, col[heap.top().SEC][0]);
        }
      }
    for (auto it : ban)
      heap.push(II(it, i));
  }
  LL rest = 1ll;
  rb(i, 1, n) if (root(i) == i) {
    sort(ALL(have[i]));
    int sum = 0, sum_ = 0, las = -1;
    for (auto it : have[i]) {
      if (las != it) {
        rest = rest * c(sum, sum_) % MOD;
        sum_ = 0;
        las = it;
      }
      sum_++;
      sum++;
    }
    rest = rest * c(sum, sum_) % MOD;
  }
  cout << rest << endl;
  return 0;
}
/** 程序框架：
 * DSU : 连边
 * 1.将同色先连边
 * 2.将异色连边
 *
 **/


Fixed submission:
/*
{
######################
#       Author       #
#        Gary        #
#        2020        #
######################
*/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define rb(a, b, c) for (int a = b; a <= c; ++a)
#define rl(a, b, c) for (int a = b; a >= c; --a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a, b) make_pair(a, b)
#define FIR first
#define SEC second
#define FREO freopen("check.out", "w", stdout)
#define rep(a, b) for (int a = 0; a < b; ++a)
#define SRAND                                                                  \
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng() % a
#define ALL(a) a.begin(), a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin >> a
#define R2(a, b) cin >> a >> b
#define check_min(a, b) a = min(a, b)
#define check_max(a, b) a = max(a, b)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> mp;
/*}
 */
const int MOD = 1e9 + 7;
LL fact[200000 + 20], rfact[200000 + 20];
LL quick(LL A, LL B) {
  if (B == 0)
    return 1;
  LL tmp = quick(A, B >> 1);
  tmp *= tmp;
  tmp %= MOD;
  if (B & 1)
    tmp *= A, tmp %= MOD;
  return tmp;
}
LL c(int A, int B) { return fact[A] * rfact[B] % MOD * rfact[A - B] % MOD; }
vector<int> have[200000 + 20];
int fa[200000 + 20];
int root(int u) { return fa[u] = (fa[u] == u ? u : root(fa[u])); }
void merge(int u, int v) {
  if (root(u) != root(v)) {
    u = root(u);
    v = root(v);
    if (have[u].size() > have[v].size()) {
      fa[v] = u;
      for (auto it : have[v])
        have[u].PB(it);
      have[v].clear();
    } else {
      fa[u] = v;
      for (auto it : have[u])
        have[v].PB(it);
      have[u].clear();
    }
  }
}
vector<int> col[200000 + 20];
int w[200000 + 20];
bool cmp(int A, int B) { return w[A] < w[B]; }
vector<int> dsu[200000 + 20];
int main() {
  fastio;
  fact[0] = 1ll;
  int n;
  int x, y;
  R(n);
  cin >> x >> y;
  rb(i, 1, 200000) fact[i] = fact[i - 1] * i % MOD;
  rfact[200000] = quick(fact[200000], MOD - 2);
  rl(i, 200000 - 1, 1) rfact[i] = rfact[i + 1] * (i + 1) % MOD;
  rfact[0] = 1;
  rb(i, 1, n) {
    int c;
    R2(c, w[i]);
    col[c].PB(i);
    have[i].PB(c);
    fa[i] = i;
  }
  rb(i, 1, n) sort(ALL(col[i]), cmp);
  priority_queue<mp, vector<mp>, greater<mp>> heap;
  rb(i, 1, n) {
    for (auto it : col[i]) {
      if (w[it] + w[col[i][0]] <= x) {
        merge(it, col[i][0]);
      }
    }
  } // 连同色边
  rb(i, 1, n) if (root(i) == i) {
    dsu[have[i][0]].PB(i);
    heap.push(II(w[col[have[i][0]][0]], have[i][0]));
  }
  rb(i, 1, n) {
    vector<int> ban;
    while (!heap.empty() && heap.top().SEC == i)
      ban.PB(heap.top().FIR), heap.pop();
    if (!heap.empty())
      for (auto it : dsu[i]) {
        if (w[it] + heap.top().FIR <= y) {
          merge(it, col[heap.top().SEC][0]);
        }
      }
    for (auto it : ban)
      heap.push(II(it, i));
  }
  LL rest = 1ll;
  rb(i, 1, n) if (root(i) == i) {
    sort(ALL(have[i]));
    int sum = 0, sum_ = 0, las = -1;
    for (auto it : have[i]) {
      if (las != it) {
        rest = rest * c(sum, sum_) % MOD;
        sum_ = 0;
        las = it;
      }
      sum_++;
      sum++;
    }
    rest = rest * c(sum, sum_) % MOD;
  }
  cout << rest << endl;
  return 0;
}
/** 程序框架：
 * DSU : 连边
 * 1.将同色先连边
 * 2.将异色连边
 *
 **/