Problem p03770 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <memory.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>

using namespace std;
typedef pair<int, int> Pi;
typedef long long ll;
#define pii Pi
#define pll PL
#define Fi first
#define Se second
#define pb(x) push_back(x)
// #define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(x) (x).begin(), (x).end()
typedef tuple<int, int, int> t3;
typedef pair<ll, ll> pll;
typedef long double ldouble;
typedef pair<double, double> pdd;

const double PI = acos(-1);
const double EPS = 1e-9;

const int MX = 100005;
const int MM = 1000000007;

pii D[MX];
vector<int> C[MX], G[MX];
ll I[MX], vst[MX], F[MX], FI[MX];
;

void dfs(int x, map<int, int> &L) {
  if (vst[x])
    return;
  vst[x] = 1;
  L[D[x].second] += 1;
  for (int c : G[x]) {
    dfs(c, L);
  }
}

void make_edge(int a, int b) {
  G[a].push_back(b);
  G[b].push_back(a);
}

int main() {
  I[1] = F[0] = FI[0] = 1;
  for (int i = 2; i < MX; i++)
    I[i] = (MM - MM / i) * I[MM % i] % MM;
  for (int i = 1; i < MX; i++)
    F[i] = F[i - 1] * i % MM;
  for (int i = 1; i < MX; i++)
    FI[i] = FI[i - 1] * I[i] % MM;

  int N, X, Y;
  scanf("%d%d%d", &N, &X, &Y);
  for (int i = 1; i <= N; i++) {
    scanf("%d%d", &D[i].second, &D[i].first);
  }
  sort(D + 1, D + N + 1);
  for (int i = 1; i <= N; i++) {
    C[D[i].second].push_back(i);
  }
  for (int i = 1; i <= N; i++) {
    sort(C[i].begin(), C[i].end());
    for (int j = 1; j < C[i].size(); j++) {
      int a = C[i][0], b = C[i][j];
      if (D[b].first + D[a].first > X)
        continue;
      make_edge(a, b);
    }
  }

  int c = D[1].second, se = 1;
  for (int i = 1; i <= N; i++) {
    if (D[i].second != c && D[i].first + D[1].first <= Y) {
      make_edge(1, i);
    }
  }
  while (se <= N && D[se].second == c)
    se++;
  if (se <= N) {
    for (int i = 1; i <= N; i++) {
      if (D[i].second != D[se].second && D[i].first + D[se].first <= Y) {
        make_edge(se, i);
      }
    }
  }

  ll ans = 1;
  for (int i = 1; i <= N; i++) {
    if (vst[i])
      continue;
    map<int, int> L;
    dfs(i, L);
    int tot = 0;
    for (auto e : L) {
      tot += e.second;
      ans = ans * FI[e.second] % MM;
    }
    ans = ans * F[tot] % MM;
  }
  printf("%lld\n", ans);
}


Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <memory.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>

using namespace std;
typedef pair<int, int> Pi;
typedef long long ll;
#define pii Pi
#define pll PL
#define Fi first
#define Se second
#define pb(x) push_back(x)
// #define sz(x) ((int)(x).size())
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(x) (x).begin(), (x).end()
typedef tuple<int, int, int> t3;
typedef pair<ll, ll> pll;
typedef long double ldouble;
typedef pair<double, double> pdd;

const double PI = acos(-1);
const double EPS = 1e-9;

const int MX = 200005;
const int MM = 1000000007;

pii D[MX];
vector<int> C[MX], G[MX];
ll I[MX], vst[MX], F[MX], FI[MX];
;

void dfs(int x, map<int, int> &L) {
  if (vst[x])
    return;
  vst[x] = 1;
  L[D[x].second] += 1;
  for (int c : G[x]) {
    dfs(c, L);
  }
}

void make_edge(int a, int b) {
  G[a].push_back(b);
  G[b].push_back(a);
}

int main() {
  I[1] = F[0] = FI[0] = 1;
  for (int i = 2; i < MX; i++)
    I[i] = (MM - MM / i) * I[MM % i] % MM;
  for (int i = 1; i < MX; i++)
    F[i] = F[i - 1] * i % MM;
  for (int i = 1; i < MX; i++)
    FI[i] = FI[i - 1] * I[i] % MM;

  int N, X, Y;
  scanf("%d%d%d", &N, &X, &Y);
  for (int i = 1; i <= N; i++) {
    scanf("%d%d", &D[i].second, &D[i].first);
  }
  sort(D + 1, D + N + 1);
  for (int i = 1; i <= N; i++) {
    C[D[i].second].push_back(i);
  }
  for (int i = 1; i <= N; i++) {
    sort(C[i].begin(), C[i].end());
    for (int j = 1; j < C[i].size(); j++) {
      int a = C[i][0], b = C[i][j];
      if (D[b].first + D[a].first > X)
        continue;
      make_edge(a, b);
    }
  }

  int c = D[1].second, se = 1;
  for (int i = 1; i <= N; i++) {
    if (D[i].second != c && D[i].first + D[1].first <= Y) {
      make_edge(1, i);
    }
  }
  while (se <= N && D[se].second == c)
    se++;
  if (se <= N) {
    for (int i = 1; i <= N; i++) {
      if (D[i].second != D[se].second && D[i].first + D[se].first <= Y) {
        make_edge(se, i);
      }
    }
  }

  ll ans = 1;
  for (int i = 1; i <= N; i++) {
    if (vst[i])
      continue;
    map<int, int> L;
    dfs(i, L);
    int tot = 0;
    for (auto e : L) {
      tot += e.second;
      ans = ans * FI[e.second] % MM;
    }
    ans = ans * F[tot] % MM;
  }
  printf("%lld\n", ans);
}