Problem p03770 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

typedef long long ll;
#define N 200100
const int Mod = 1000000007;

int c[N], w[N], fac[N], fac_inv[N], cnt[N];
vector<pair<int, int>> color_list[N];
vector<int> E[N];
bool vis[N], vis_color[N];
vector<int> color;

int Power(int x, int p) {
  int res = 1;
  for (; p; p >>= 1) {
    if (p & 1)
      res = 1ll * res * x % Mod;
    x = 1ll * x * x % Mod;
  }
  return res;
}

void Add_Edge(int x, int y) {

  E[x].push_back(y);
  E[y].push_back(x);
}

void Dfs(int x, int &tot) {
  cnt[c[x]]++;
  tot++;
  if (!vis_color[x]) {
    vis_color[x] = true;
    color.push_back(c[x]);
  }

  for (int i = 0; i < E[x].size(); i++) {
    int y = E[x][i];
    if (vis[y])
      continue;
    vis[y] = true;
    Dfs(y, tot);
  }
}

int C(int n, int m) {
  if (m == 0)
    return 1;
  if (n == 0)
    return 0;
  int res = 1ll * fac[n] * fac_inv[m] % Mod;
  return 1ll * res * fac_inv[n - m] % Mod;
}

int main() {
  // freopen("in.in","r",stdin);
  // freopen("out.out","w",stdout);

  int n, X, Y, a = 0, b = 0;
  scanf("%d%d%d", &n, &X, &Y);
  for (int i = 1; i <= n; i++)
    scanf("%d%d", &c[i], &w[i]), color_list[c[i]].push_back(make_pair(w[i], i));
  for (int i = 1; i <= n; i++) {
    if (color_list[i].empty())
      continue;
    sort(color_list[i].begin(), color_list[i].end());
    for (int j = 1; j < color_list[i].size(); j++) {
      if (color_list[i][0].first + color_list[i][j].first > X)
        break;
      Add_Edge(color_list[i][0].second, color_list[i][j].second);
    }
    if (!a) {
      b = a, a = color_list[i][0].second;
      continue;
    }
    if (color_list[i][0].first < w[a])
      b = a, a = color_list[i][0].second;
    else if (!b || color_list[i][0].first < w[b])
      b = color_list[i][0].second;
  }
  if (a)
    for (int i = 1; i <= n; i++)
      if (c[i] != c[a] && w[i] + w[a] <= Y)
        Add_Edge(a, i);
  if (b)
    for (int i = 1; i <= n; i++)
      if (c[i] != c[b] && w[i] + w[b] <= Y)
        Add_Edge(b, i);

  fac[0] = fac_inv[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = 1ll * fac[i - 1] * i % Mod, fac_inv[i] = Power(fac[i], Mod - 2);

  int ans = 1;
  for (int i = 1; i <= n; i++) {
    if (vis[i])
      continue;
    int tot = 0;
    vis[i] = true, Dfs(i, tot);
    for (int j = 0; j < color.size(); j++) {
      ans = 1ll * ans * C(tot, cnt[color[j]]) % Mod;
      tot -= cnt[color[j]];
      vis_color[color[j]] = false, cnt[color[j]] = 0;
    }
  }
  printf("%d\n", ans);

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

typedef long long ll;
#define N 200100
const int Mod = 1000000007;

int c[N], w[N], fac[N], fac_inv[N], cnt[N];
vector<pair<int, int>> color_list[N];
vector<int> E[N];
bool vis[N], vis_color[N];
vector<int> color;

int Power(int x, int p) {
  int res = 1;
  for (; p; p >>= 1) {
    if (p & 1)
      res = 1ll * res * x % Mod;
    x = 1ll * x * x % Mod;
  }
  return res;
}

void Add_Edge(int x, int y) {

  E[x].push_back(y);
  E[y].push_back(x);
}

void Dfs(int x, int &tot) {
  cnt[c[x]]++;
  tot++;
  if (!vis_color[x]) {
    vis_color[x] = true;
    color.push_back(c[x]);
  }

  for (int i = 0; i < E[x].size(); i++) {
    int y = E[x][i];
    if (vis[y])
      continue;
    vis[y] = true;
    Dfs(y, tot);
  }
}

int C(int n, int m) {
  if (m == 0)
    return 1;
  if (n == 0)
    return 0;
  int res = 1ll * fac[n] * fac_inv[m] % Mod;
  return 1ll * res * fac_inv[n - m] % Mod;
}

int main() {
  // freopen("in.in","r",stdin);
  // freopen("out.out","w",stdout);

  int n, X, Y, a = 0, b = 0;
  scanf("%d%d%d", &n, &X, &Y);
  for (int i = 1; i <= n; i++)
    scanf("%d%d", &c[i], &w[i]), color_list[c[i]].push_back(make_pair(w[i], i));
  for (int i = 1; i <= n; i++) {
    if (color_list[i].empty())
      continue;
    sort(color_list[i].begin(), color_list[i].end());
    for (int j = 1; j < color_list[i].size(); j++) {
      if (color_list[i][0].first + color_list[i][j].first > X)
        break;
      Add_Edge(color_list[i][0].second, color_list[i][j].second);
    }
    if (!a) {
      b = a, a = color_list[i][0].second;
      continue;
    }
    if (color_list[i][0].first < w[a])
      b = a, a = color_list[i][0].second;
    else if (!b || color_list[i][0].first < w[b])
      b = color_list[i][0].second;
  }
  if (a)
    for (int i = 1; i <= n; i++)
      if (c[i] != c[a] && w[i] + w[a] <= Y)
        Add_Edge(a, i);
  if (b)
    for (int i = 1; i <= n; i++)
      if (c[i] != c[b] && w[i] + w[b] <= Y)
        Add_Edge(b, i);

  fac[0] = fac_inv[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = 1ll * fac[i - 1] * i % Mod, fac_inv[i] = Power(fac[i], Mod - 2);

  int ans = 1;
  for (int i = 1; i <= n; i++) {
    if (vis[i])
      continue;
    int tot = 0;
    vis[i] = true, Dfs(i, tot);
    for (int j = 0; j < color.size(); j++) {
      ans = 1ll * ans * C(tot, cnt[color[j]]) % Mod;
      tot -= cnt[color[j]];
      vis_color[color[j]] = false, cnt[color[j]] = 0;
    }
    color.clear();
  }
  printf("%d\n", ans);

  return 0;
}