Problem p02540 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

// Verified: AOJ-DSL1A, AGC002D
class UFSet {
private:
  vector<int> ranks;
  vector<int> prevs;
  vector<int> sizes;

public:
  UFSet(int n) : ranks(n), prevs(n), sizes(n) {
    for (int i = 0; i < n; i++)
      prevs[i] = i;
    for (int i = 0; i < n; i++)
      sizes[i] = 1;
  }

  // Returns an ID of a set which x belongs to.
  int Find(int x) {
    if (x != prevs[x])
      prevs[x] = Find(prevs[x]);
    return prevs[x];
  }

  // Merges a set which x blongs to and a set which y belongs to.
  void Union(int x, int y) {
    int x_root = Find(x);
    int y_root = Find(y);
    if (ranks[x_root] > ranks[y_root]) {
      prevs[y_root] = prevs[x_root];
      sizes[x_root] += sizes[y_root];
    } else if (ranks[x_root] < ranks[y_root]) {
      prevs[x_root] = prevs[y_root];
      sizes[y_root] += sizes[x_root];
    } else if (prevs[x_root] != prevs[y_root]) {
      prevs[y_root] = prevs[x_root];
      ranks[x_root]++;
      sizes[x_root] += sizes[y_root];
    }
  }

  // Returns a size of a set which x belongs to.
  int Size(int x) { return sizes[Find(x)]; }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<tuple<int, int>> ps(n);
  vector<int> original_xs(n);
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    ps[i] = {x, y};
    original_xs[i] = x;
  }
  sort(ps.begin(), ps.end(),
       [](const auto &p1, const auto &p2) { return get<1>(p1) > get<1>(p2); });

  UFSet uf_set(n);
  set<int> s;

  for (const auto [x, y] : ps) {
    if (s.empty()) {
      s.insert(x);
    } else if (*s.rbegin() < x) {
      s.insert(x);
    } else {
      vector<int> remove_vector;
      for (auto it = s.rbegin(); it != s.rend(); it++) {
        if (*it > x) {
          if (it != s.rbegin())
            remove_vector.push_back(*it);
        }
      }
      for (int rx : remove_vector) {
        // cout << rx << " " << *s.rbegin() << endl;
        uf_set.Union(rx, *s.rbegin());
        s.erase(rx);
      }
      uf_set.Union(x, *s.rbegin());
    }

    // DUMP
    // for (int sx : s) {
    //   cout << sx << " ";
    // }
    // cout << endl;
  }

  for (int i = 0; i < n; i++) {
    cout << uf_set.Size(original_xs[i]) << "\n";
  }
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

// Verified: AOJ-DSL1A, AGC002D
class UFSet {
private:
  vector<int> ranks;
  vector<int> prevs;
  vector<int> sizes;

public:
  UFSet(int n) : ranks(n), prevs(n), sizes(n) {
    for (int i = 0; i < n; i++)
      prevs[i] = i;
    for (int i = 0; i < n; i++)
      sizes[i] = 1;
  }

  // Returns an ID of a set which x belongs to.
  int Find(int x) {
    if (x != prevs[x])
      prevs[x] = Find(prevs[x]);
    return prevs[x];
  }

  // Merges a set which x blongs to and a set which y belongs to.
  void Union(int x, int y) {
    int x_root = Find(x);
    int y_root = Find(y);
    if (ranks[x_root] > ranks[y_root]) {
      prevs[y_root] = prevs[x_root];
      sizes[x_root] += sizes[y_root];
    } else if (ranks[x_root] < ranks[y_root]) {
      prevs[x_root] = prevs[y_root];
      sizes[y_root] += sizes[x_root];
    } else if (prevs[x_root] != prevs[y_root]) {
      prevs[y_root] = prevs[x_root];
      ranks[x_root]++;
      sizes[x_root] += sizes[y_root];
    }
  }

  // Returns a size of a set which x belongs to.
  int Size(int x) { return sizes[Find(x)]; }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<tuple<int, int>> ps(n);
  vector<int> original_xs(n);
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    ps[i] = {x, y};
    original_xs[i] = x;
  }
  sort(ps.begin(), ps.end(),
       [](const auto &p1, const auto &p2) { return get<1>(p1) > get<1>(p2); });

  UFSet uf_set(n);
  set<int> s;

  for (const auto [x, y] : ps) {
    if (s.empty()) {
      s.insert(x);
    } else if (*s.rbegin() < x) {
      s.insert(x);
    } else {
      vector<int> remove_vector;
      for (auto it = s.rbegin(); it != s.rend(); it++) {
        if (*it > x) {
          if (it != s.rbegin())
            remove_vector.push_back(*it);
        } else {
          break;
        }
      }
      for (int rx : remove_vector) {
        // cout << rx << " " << *s.rbegin() << endl;
        uf_set.Union(rx, *s.rbegin());
        s.erase(rx);
      }
      uf_set.Union(x, *s.rbegin());
    }

    // DUMP
    // for (int sx : s) {
    //   cout << sx << " ";
    // }
    // cout << endl;
  }

  for (int i = 0; i < n; i++) {
    cout << uf_set.Size(original_xs[i]) << "\n";
  }
}