Problem p01526 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
using namespace std;
class UnionFind {
private:
  unsigned size_;
  std::vector<unsigned> par, rank;

public:
  UnionFind()
      : size_(0), par(std::vector<unsigned>()), rank(std::vector<unsigned>()){};
  UnionFind(unsigned size__) : size_(size__) {
    par.resize(size_);
    rank.resize(size_);
    for (unsigned i = 0; i < size_; i++)
      par[i] = i, rank[i] = 0;
  }
  unsigned size() { return size_; }
  unsigned root(unsigned x) { return par[x] == x ? x : par[x] = root(par[x]); }
  bool same(unsigned x, unsigned y) { return root(x) == root(y); }
  void unite(unsigned x, unsigned y) {
    x = root(x), y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else if (rank[x] == rank[y])
      par[y] = x, rank[x]++;
    else
      par[y] = x;
  }
  bool operator==(const UnionFind &u) { return par == u.par; }
  bool operator!=(const UnionFind &u) { return par != u.par; }
};
int n;
long double x[200000], y[200000], R, r1 = 0.1145141919, r2 = 0.9868864999;
bool used[200000];
tuple<long double, long double, int> p[200000];
long double dst(long double px, long double py, long double qx,
                long double qy) {
  return sqrtl((px - qx) * (px - qx) + (py - qy) * (py - qy));
}
int main() {
  cin >> n >> R;
  int ans = 0;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    x[i] *= r2;
    y[i] *= r2;
    long double J1 = x[i], J2 = y[i];
    J1 *= r1 / r2;
    J2 *= r1 / r2;
    x[i] -= J2;
    y[i] += J1;
    p[i] = make_tuple(x[i], y[i], i);
  }
  sort(p, p + n);
  UnionFind UF(n);
  for (int i = 0; i < n; i++) {
    if (used[i] == true)
      continue;
    ans++;
    used[i] = true;
    int pos1 = lower_bound(p, p + n, make_tuple(x[i] - R, y[i], i)) - p;
    int pos2 = lower_bound(p, p + n, make_tuple(x[i] + R, y[i], i)) - p;
    for (int j = pos1; j < pos2; j++) {
      if (dst(x[i], y[i], get<0>(p[j]), get<1>(p[j])) <= R * 1.001l) {
        if (UF.same(i, get<2>(p[j])) == false) {
          UF.unite(i, get<2>(p[j]));
          used[get<2>(p[j])] = true;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define MAX_N 241200
double x[MAX_N], y[MAX_N], c[MAX_N], R;
pair<double, int> X[MAX_N], Y[MAX_N];
int group[MAX_N];
queue<int> Q;
vector<int> gr[1 << 18];
void unite(int a, int b) {
  int L = group[a], M = group[b];
  if (group[a] != group[b] && gr[L].size() >= gr[M].size()) {
    for (int j = 0; j < gr[M].size(); j++) {
      group[gr[M][j]] = L;
      gr[L].push_back(gr[M][j]);
    }
    gr[M].clear();
  } else if (group[a] != group[b]) {
    for (int j = 0; j < gr[L].size(); j++) {
      group[gr[L][j]] = M;
      gr[M].push_back(gr[L][j]);
    }
    gr[L].clear();
  }
}
int main() {
  srand((unsigned)time(NULL));
  for (int i = 0; i < MAX_N; i++) {
    group[i] = i;
    gr[i].clear();
    gr[i].push_back(i);
  }
  int n;
  cin >> n >> R;
  for (int i = 0; i < n; i++) {
    cin >> x[i] >> y[i];
    X[i] = make_pair(x[i], i);
    Y[i] = make_pair(y[i], i);
  }
  int cnt = 0;
  sort(X, X + n);
  sort(Y, Y + n);
  int T = 1;
  if (n >= 100000)
    T = 5;
  for (int t = 0; t < n; t++) {
    if (c[t] >= 1)
      continue;
    Q.push(t);
    while (!Q.empty()) {
      int i = Q.front();
      Q.pop();
      if (c[i] == 2)
        continue;
      c[i] = 2;
      double LX = x[i] - R, RX = x[i] + R;
      double LY = y[i] - R, RY = y[i] + R;
      int pos1 = lower_bound(X, X + n, make_pair(LX, 0)) - X;
      int pos2 = lower_bound(X, X + n, make_pair(RX, MAX_N)) - X;
      int pos3 = lower_bound(Y, Y + n, make_pair(LY, 0)) - Y;
      int pos4 = lower_bound(Y, Y + n, make_pair(RY, MAX_N)) - Y;
      int gap1 = pos2 - pos1;
      int gap2 = pos4 - pos3;
      if (rand() % T >= 3)
        continue;
      if (gap1 <= gap2) {
        for (int j = pos1; j < pos2; j++) {
          if (c[X[j].second] >= 1)
            continue;
          int to = X[j].second;
          double dist =
              (x[i] - x[to]) * (x[i] - x[to]) + (y[i] - y[to]) * (y[i] - y[to]);
          if (group[i] != group[to] && dist <= R * R) {
            unite(i, to);
            Q.push(to);
            c[to] = 1;
          }
        }
      }
      if (gap1 > gap2) {
        for (int j = pos3; j < pos4; j++) {
          if (c[Y[j].second] >= 1)
            continue;
          int to = Y[j].second;
          double dist =
              (x[i] - x[to]) * (x[i] - x[to]) + (y[i] - y[to]) * (y[i] - y[to]);
          if (group[i] != group[to] && dist <= R) {
            unite(i, to);
            Q.push(to);
            c[to] = 1;
          }
        }
      }
    }
  }
  for (int i = 0; i < n; i++) {
    if (gr[i].size() >= 1)
      cnt++;
  }
  cout << cnt << endl;
  return 0;
}