Problem p02680 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

// one-based numbering
struct UnionFind {
  vector<int> data;
  // i: (data[i] < 0) -> group size, (data[i] > 0) -> parent;
  UnionFind(int n) { data.resize(n + 1, -1); }
  int find(int x) {
    if (data[x] < 0)
      return x;
    else
      return data[x] = find(data[x]);
  }
  int size(int x) { return -data[find(x)]; }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  bool same(int x, int y) {
    x = find(x);
    y = find(y);
    return x == y;
  }
};

bool V[9100000][2];

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

  int N, M;
  cin >> N >> M;
  vector<long long> A(N), B(N), C(N), D(M), E(M), F(M);
  vector<long long> X, Y;

  for (int i = 0; i < N; i++) {
    cin >> A[i] >> B[i] >> C[i];
    X.emplace_back(A[i]);
    X.emplace_back(B[i]);
    Y.emplace_back(C[i]);
  }
  for (int i = 0; i < M; i++) {
    cin >> D[i] >> E[i] >> F[i];
    X.emplace_back(D[i]);
    Y.emplace_back(E[i]);
    Y.emplace_back(F[i]);
  }

  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  sort(Y.begin(), Y.end());
  Y.erase(unique(Y.begin(), Y.end()), Y.end());

  int Xs = X.size(), Ys = Y.size();
  auto encode = [&](int i, int j) { return i * (Ys + 1) + j + 1; };

  for (int i = 0; i < N; i++) {
    int a = A[i], b = B[i], c = C[i];
    int xl = lower_bound(X.begin(), X.end(), a) - X.begin();
    int xr = lower_bound(X.begin(), X.end(), b) - X.begin();
    int y = lower_bound(Y.begin(), Y.end(), c) - Y.begin();
    for (int x = xl + 1; x <= xr; x++) {
      V[encode(x, y)][0] = true;
    }
  }
  for (int i = 0; i < M; i++) {
    int d = D[i], e = E[i], f = F[i];
    int x = lower_bound(X.begin(), X.end(), d) - X.begin();
    int yl = lower_bound(Y.begin(), Y.end(), e) - Y.begin();
    int yr = lower_bound(Y.begin(), Y.end(), f) - Y.begin();
    for (int y = yl + 1; y <= yr; y++) {
      V[encode(x, y)][1] = true;
    }
  }

  UnionFind uf((Xs + 1) * (Ys + 1));

  for (int i = 0; i <= Xs; i++) {
    for (int j = 0; j <= Ys; j++) {
      int cur = encode(i, j);
      int s = encode(i + 1, j);
      int t = encode(i, j + 1);
      if (!V[cur][0])
        uf.unite(cur, t);
      if (!V[cur][1])
        uf.unite(cur, s);
    }
  }

  int xz = lower_bound(X.begin(), X.end(), 0LL) - X.begin();
  int yz = lower_bound(Y.begin(), Y.end(), 0LL) - Y.begin();
  int Z = encode(xz, yz);

  long long ans = 0;
  for (int i = 0; i <= Xs; i++) {
    for (int j = 0; j <= Ys; j++) {
      int cur = encode(i, j);
      if (!uf.same(cur, Z))
        continue;
      if (i == 0 || j == 0 || i == Xs || j == Ys) {
        cout << "INF\n";
        return 0;
      }
      ans += (X[i] - X[i - 1]) * (Y[j] - Y[j - 1]);
    }
  }

  cout << ans << "\n";

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

// one-based numbering
struct UnionFind {
  vector<int> data;
  // i: (data[i] < 0) -> group size, (data[i] > 0) -> parent;
  UnionFind(int n) { data.resize(n + 1, -1); }
  int find(int x) {
    if (data[x] < 0)
      return x;
    else
      return data[x] = find(data[x]);
  }
  int size(int x) { return -data[find(x)]; }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  bool same(int x, int y) {
    x = find(x);
    y = find(y);
    return x == y;
  }
};

bool V[9100000][2];

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

  int N, M;
  cin >> N >> M;
  vector<long long> A(N), B(N), C(N), D(M), E(M), F(M);
  vector<long long> X, Y;

  for (int i = 0; i < N; i++) {
    cin >> A[i] >> B[i] >> C[i];
    X.emplace_back(A[i]);
    X.emplace_back(B[i]);
    Y.emplace_back(C[i]);
  }
  for (int i = 0; i < M; i++) {
    cin >> D[i] >> E[i] >> F[i];
    X.emplace_back(D[i]);
    Y.emplace_back(E[i]);
    Y.emplace_back(F[i]);
  }

  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  sort(Y.begin(), Y.end());
  Y.erase(unique(Y.begin(), Y.end()), Y.end());

  int Xs = X.size(), Ys = Y.size();
  auto encode = [&](int i, int j) { return i * (Ys + 1) + j + 1; };

  for (int i = 0; i < N; i++) {
    int a = A[i], b = B[i], c = C[i];
    int xl = lower_bound(X.begin(), X.end(), a) - X.begin();
    int xr = lower_bound(X.begin(), X.end(), b) - X.begin();
    int y = lower_bound(Y.begin(), Y.end(), c) - Y.begin();
    for (int x = xl + 1; x <= xr; x++) {
      V[encode(x, y)][0] = true;
    }
  }
  for (int i = 0; i < M; i++) {
    int d = D[i], e = E[i], f = F[i];
    int x = lower_bound(X.begin(), X.end(), d) - X.begin();
    int yl = lower_bound(Y.begin(), Y.end(), e) - Y.begin();
    int yr = lower_bound(Y.begin(), Y.end(), f) - Y.begin();
    for (int y = yl + 1; y <= yr; y++) {
      V[encode(x, y)][1] = true;
    }
  }

  UnionFind uf((Xs + 1) * (Ys + 1));

  for (int i = 0; i < Xs; i++) {
    for (int j = 0; j < Ys; j++) {
      int cur = encode(i, j);
      int s = encode(i + 1, j);
      int t = encode(i, j + 1);
      if (!V[cur][0])
        uf.unite(cur, t);
      if (!V[cur][1])
        uf.unite(cur, s);
    }
  }

  int xz = lower_bound(X.begin(), X.end(), 0LL) - X.begin();
  int yz = lower_bound(Y.begin(), Y.end(), 0LL) - Y.begin();
  int Z = encode(xz, yz);

  long long ans = 0;
  for (int i = 0; i <= Xs; i++) {
    for (int j = 0; j <= Ys; j++) {
      int cur = encode(i, j);
      if (!uf.same(cur, Z))
        continue;
      if (i == 0 || j == 0 || i == Xs || j == Ys) {
        cout << "INF\n";
        return 0;
      }
      ans += (X[i] - X[i - 1]) * (Y[j] - Y[j - 1]);
    }
  }

  cout << ans << "\n";

  return 0;
}