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

#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define REP(i, m, n) for (ll i = (ll)(m); i < (ll)(n); i++)
#define fi first
#define se second
long long mo = 1000000007;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;
typedef pair<ll, Pll> PlP;
template <class T, class S> void cmin(T &a, const S &b) {
  if (a > b)
    a = b;
}
template <class T, class S> void cmax(T &a, const S &b) {
  if (a < b)
    a = b;
}
template <class A> void PR(A a, ll n) {
  rep(i, n) {
    if (i)
      cout << ' ';
    cout << a[i];
  }
  cout << "\\n";
}
ld PI = 3.14159265358979323846;
// using namespace atcoder;

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
  vector<int> size;
  UnionFind(int N) : par(N), size(N) {

    // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++) {
      par[i] = i;
      size[i] = -1;
    }
  }
  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    size[ry] += size[rx];
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
  int getsize(int x) { return -size[root(x)]; }
  int getNunion() { // これちょっと遅い
                    // sameと組み合わせて順次数えていけば早くなりそう。
    map<int, int> m;
    rep(i, par.size()) { m[this->root(i)]++; }
    return int(m.size());
  }
};

int main() {
  ll N;
  cin >> N;
  vector<ll> x(N), y(N), id(N);
  vector<Pll> p(N);
  rep(i, N) {
    cin >> x[i] >> y[i];
    p[i] = {x[i], y[i]};
    id[i] = x[i] - 1;
  }
  sort(p.begin(), p.end());
  UnionFind tr(N);
  set<Pll> my;
  /*Pll my = p[0];
  rep(i,N){
      ll yy = p[i].se;
      if(my.fi < yy){
          tr.unite(my.se,i);
      }
      cmin(my,Pll(yy,i));
  }*/
  rep(i, N) {
    // ll xx = p[i].fi;
    ll yy = p[i].se;
    bool flag = 0;
    // Pll abc = *my.begin();
    for (auto &pp : my) {
      if (pp.fi < yy) {
        tr.unite(i, pp.se);
        // my.erase(pp);
        flag = 1;
        // break;
      } else {
        break;
      }
    }
    // my.insert(abc);
    if (!flag) {
      my.insert({yy, i});
    } else {
      Pll tmp = *my.begin();
      for (auto &e : my) {
        if (e.fi < yy) {
          my.erase(e);
        } else {
          break;
        }
      }
      // auto itr = lower_bound(my.begin(),my.end(),Pll(yy,-1));
      // my.erase(my.begin(), itr);
      my.insert(tmp);
    }
  }
  rep(i, N) { cout << tr.getsize(id[i]) << endl; }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define REP(i, m, n) for (ll i = (ll)(m); i < (ll)(n); i++)
#define fi first
#define se second
long long mo = 1000000007;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;
typedef pair<ll, Pll> PlP;
template <class T, class S> void cmin(T &a, const S &b) {
  if (a > b)
    a = b;
}
template <class T, class S> void cmax(T &a, const S &b) {
  if (a < b)
    a = b;
}
template <class A> void PR(A a, ll n) {
  rep(i, n) {
    if (i)
      cout << ' ';
    cout << a[i];
  }
  cout << "\\n";
}
ld PI = 3.14159265358979323846;
// using namespace atcoder;

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
  vector<int> size;
  UnionFind(int N) : par(N), size(N) {

    // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++) {
      par[i] = i;
      size[i] = -1;
    }
  }
  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    size[ry] += size[rx];
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
  int getsize(int x) { return -size[root(x)]; }
  int getNunion() { // これちょっと遅い
                    // sameと組み合わせて順次数えていけば早くなりそう。
    map<int, int> m;
    rep(i, par.size()) { m[this->root(i)]++; }
    return int(m.size());
  }
};

int main() {
  ll N;
  cin >> N;
  vector<ll> x(N), y(N), id(N);
  vector<Pll> p(N);
  rep(i, N) {
    cin >> x[i] >> y[i];
    p[i] = {x[i], y[i]};
    id[i] = x[i] - 1;
  }
  sort(p.begin(), p.end());
  UnionFind tr(N);
  set<Pll> my;
  rep(i, N) {
    // ll xx = p[i].fi;
    ll yy = p[i].se;
    bool flag = 0;
    for (auto &pp : my) {
      if (pp.fi < yy) {
        tr.unite(i, pp.se);
        flag = 1;
      } else {
        break;
      }
    }
    if (!flag) {
      my.insert({yy, i});
    } else {
      Pll tmp = *my.begin();
      auto itr = lower_bound(my.begin(), my.end(), Pll(yy, -1));
      my.erase(my.begin(), itr);
      my.insert(tmp);
    }
  }
  rep(i, N) { cout << tr.getsize(id[i]) << endl; }
}