Problem p03770 (C++)

Buggy submission (status: Runtime Error):
// Crt. 2019-12-17  12:14:28
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#define N 100005
using namespace std;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;

inline int fsp(int x, int p = Mod - 2) {
  int res = 1;
  while (p) {
    if (p & 1)
      res = 1ll * res * x % Mod;
    x = 1ll * x * x % Mod, p >>= 1;
  }
  return res;
}

int n, x, y, fa[N], d[N], fac[N], ifac[N];
vector<int> c[N], G[N];

inline int find(int u) { return fa[u] == u ? u : fa[u] = find(fa[u]); }

inline void addE(int a, int b) { fa[find(a)] = find(b); }

inline void check(int &a, int &ai, int &b, int &bi, int z, int zi) {
  if (z < b)
    swap(z, b), swap(zi, bi);
  if (b < a)
    swap(b, a), swap(bi, ai);
  if (z < b)
    swap(z, b), swap(zi, bi);
}

int main() {
#ifdef LOCAL_JUDGE
  freopen("work.in", "r", stdin);
  freopen("work.out", "w", stdout);
#endif

  cin >> n >> x >> y;

  for (int i = fac[0] = 1; i <= n; ++i)
    fac[i] = 1ll * fac[i - 1] * i % Mod, fa[i] = i;
  ifac[n] = fsp(fac[n]);
  for (int i = n; i >= 1; --i)
    ifac[i - 1] = 1ll * ifac[i] * i % Mod;

  for (int i = 1, u, v; i <= n; ++i)
    scanf("%d%d", &u, &v), c[u].push_back(v);

  int a = INF, b = INF, ai = 0, bi = 0, cnt = 0;
  for (int i = 1, tmp; i <= n; ++i) {
    if (!c[i].size())
      continue;
    sort(c[i].begin(), c[i].end());
    check(a, ai, b, bi, c[i][0], (tmp = ++cnt));
    d[cnt] = i;
    for (int j = 1, sz = c[i].size(); j < sz; ++j) {
      d[++cnt] = i;
      if (c[i][j] + c[i][0] <= x)
        addE(tmp, cnt);
    }
  }

  cnt = 0;
  for (int i = 1, t, ti; i <= n; ++i) {
    if (!c[i].size())
      continue;
    if (d[ai] == i)
      t = b, ti = bi;
    else
      t = a, ti = ai;
    for (int j = 0, sz = c[i].size(); j < sz; ++j) {
      ++cnt;
      if (c[i][j] + t <= y)
        addE(ti, cnt);
    }
  }

  for (int i = 1; i <= cnt; ++i)
    G[find(i)].push_back(d[i]);

  int ans = 1;

  for (int i = 1; i <= cnt; ++i) {
    if (!G[i].size())
      continue;
    sort(G[i].begin(), G[i].end());
    int now = 0;
    ans = 1ll * ans * fac[G[i].size()] % Mod;
    for (int j = 0, sz = G[i].size(); j < sz; ++j) {
      if (j && G[i][j] != G[i][j - 1])
        ans = 1ll * ans * ifac[now] % Mod, now = 1;
      else
        ++now;
    }
    ans = 1ll * ans * ifac[now] % Mod;
  }

  cout << ans << endl;

  return 0;
}


Fixed submission:
// Crt. 2019-12-17  12:14:28
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#define N 500005
using namespace std;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;

inline int fsp(int x, int p = Mod - 2) {
  int res = 1;
  while (p) {
    if (p & 1)
      res = 1ll * res * x % Mod;
    x = 1ll * x * x % Mod, p >>= 1;
  }
  return res;
}

int n, x, y, fa[N], d[N], fac[N], ifac[N];
vector<int> c[N], G[N];

inline int find(int u) { return fa[u] == u ? u : fa[u] = find(fa[u]); }

inline void addE(int a, int b) { fa[find(a)] = find(b); }

inline void check(int &a, int &ai, int &b, int &bi, int z, int zi) {
  if (z < b)
    swap(z, b), swap(zi, bi);
  if (b < a)
    swap(b, a), swap(bi, ai);
  if (z < b)
    swap(z, b), swap(zi, bi);
}

int main() {
#ifdef LOCAL_JUDGE
  freopen("work.in", "r", stdin);
  freopen("work.out", "w", stdout);
#endif

  cin >> n >> x >> y;

  for (int i = fac[0] = 1; i <= n; ++i)
    fac[i] = 1ll * fac[i - 1] * i % Mod, fa[i] = i;
  ifac[n] = fsp(fac[n]);
  for (int i = n; i >= 1; --i)
    ifac[i - 1] = 1ll * ifac[i] * i % Mod;

  for (int i = 1, u, v; i <= n; ++i)
    scanf("%d%d", &u, &v), c[u].push_back(v);

  int a = INF, b = INF, ai = 0, bi = 0, cnt = 0;
  for (int i = 1, tmp; i <= n; ++i) {
    if (!c[i].size())
      continue;
    sort(c[i].begin(), c[i].end());
    check(a, ai, b, bi, c[i][0], (tmp = ++cnt));
    d[cnt] = i;
    for (int j = 1, sz = c[i].size(); j < sz; ++j) {
      d[++cnt] = i;
      if (c[i][j] + c[i][0] <= x)
        addE(tmp, cnt);
    }
  }

  cnt = 0;
  for (int i = 1, t, ti; i <= n; ++i) {
    if (!c[i].size())
      continue;
    if (d[ai] == i)
      t = b, ti = bi;
    else
      t = a, ti = ai;
    for (int j = 0, sz = c[i].size(); j < sz; ++j) {
      ++cnt;
      if (c[i][j] + t <= y)
        addE(ti, cnt);
    }
  }

  for (int i = 1; i <= cnt; ++i)
    G[find(i)].push_back(d[i]);

  int ans = 1;

  for (int i = 1; i <= cnt; ++i) {
    if (!G[i].size())
      continue;
    sort(G[i].begin(), G[i].end());
    int now = 0;
    ans = 1ll * ans * fac[G[i].size()] % Mod;
    for (int j = 0, sz = G[i].size(); j < sz; ++j) {
      if (j && G[i][j] != G[i][j - 1])
        ans = 1ll * ans * ifac[now] % Mod, now = 1;
      else
        ++now;
    }
    ans = 1ll * ans * ifac[now] % Mod;
  }

  cout << ans << endl;

  return 0;
}