Problem p02680 (C++)

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

template <typename T> vector<T> compress(vector<T> A) {
  sort(A.begin(), A.end());
  A.erase(unique(A.begin(), A.end()), A.end());
  return A;
}

struct UnionFind {
  vector<int> par;
  vector<int> sz;

  UnionFind(int n = 0) {
    if (n > 0)
      initialize(n);
  }
  void initialize(int n) {
    par.resize(n);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return false;
    if (sz[x] > sz[y])
      swap(x, y);
    par[x] = y;
    sz[y] += sz[x];
    return true;
  }

  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sz[find(x)]; }
};

int main() {
  int N, M;
  cin >> N >> M;
  int64_t INF = 2e9;
  vector<int64_t> xs = {-INF, INF}, ys = {-INF, INF};
  auto add = [&](int64_t x, int64_t y) {
    xs.push_back(x);
    xs.push_back(x + 1);
    ys.push_back(y);
    ys.push_back(y + 1);
  };

  vector<int64_t> A(N), B(N), C(N), D(M), E(M), F(M);
  for (int i = 0; i < N; i++) {
    cin >> A[i] >> B[i] >> C[i];
    add(A[i], C[i]);
    add(B[i], C[i]);
  }
  for (int i = 0; i < M; i++) {
    cin >> D[i] >> E[i] >> F[i];
    add(D[i], E[i]);
    add(D[i], F[i]);
  }
  xs = compress(xs);
  ys = compress(ys);
  auto find_x = [&](int a) -> int {
    return upper_bound(xs.begin(), xs.end(), a) - xs.begin() - 1;
  };
  auto find_y = [&](int a) -> int {
    return upper_bound(ys.begin(), ys.end(), a) - ys.begin() - 1;
  };

  int xsz = xs.size(), ysz = ys.size();
  bitset<4001> under[4000], right[4000];
  for (int i = 0; i < N; i++) {
    A[i] = find_x(A[i]);
    B[i] = find_x(B[i]);
    C[i] = find_y(C[i]);
    for (int x = A[i] + 1; x <= B[i]; x++)
      right[x][C[i]] = 1;
  }
  for (int i = 0; i < M; i++) {
    D[i] = find_x(D[i]);
    E[i] = find_y(E[i]);
    F[i] = find_y(F[i]);
    for (int y = E[i] + 1; y <= F[i]; y++)
      under[D[i]][y] = 1;
  }
  auto encode = [&](int i, int j) { return i * ysz + j; };
  UnionFind uf(xsz * ysz);
  for (int i = 0; i < xsz - 1; i++)
    for (int j = 0; j < ysz - 1; j++) {
      if (!under[i][j])
        uf.unite(encode(i, j), encode(i + 1, j));
      if (!right[i][j])
        uf.unite(encode(i, j), encode(i, j + 1));
    }

  auto fail = []() {
    cout << "INF" << endl;
    exit(0);
  };
  int cow = encode(find_x(0), find_y(0));
  int64_t ans = 0;
  for (int i = 0; i < xsz; i++)
    for (int j = 0; j < ysz; j++)
      if (uf.same(cow, encode(i, j))) {
        if (i == 0 || i == xsz - 1 || j == 0 || j == ysz - 1)
          fail();
        int64_t dx = xs[i + 1] - xs[i], dy = ys[j + 1] - ys[j];
        ans += dx * dy;
      }
  cout << ans << endl;
  return 0;
}


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

template <typename T> vector<T> compress(vector<T> A) {
  sort(A.begin(), A.end());
  A.erase(unique(A.begin(), A.end()), A.end());
  return A;
}

struct UnionFind {
  vector<int> par;
  vector<int> sz;

  UnionFind(int n = 0) {
    if (n > 0)
      initialize(n);
  }
  void initialize(int n) {
    par.resize(n);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return false;
    if (sz[x] > sz[y])
      swap(x, y);
    par[x] = y;
    sz[y] += sz[x];
    return true;
  }

  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sz[find(x)]; }
};

int main() {
  int N, M;
  cin >> N >> M;
  int64_t INF = 2e9;
  vector<int64_t> xs = {-INF, INF}, ys = {-INF, INF};
  auto add = [&](int64_t x, int64_t y) {
    xs.push_back(x);
    xs.push_back(x + 1);
    ys.push_back(y);
    ys.push_back(y + 1);
  };

  vector<int64_t> A(N), B(N), C(N), D(M), E(M), F(M);
  for (int i = 0; i < N; i++) {
    cin >> A[i] >> B[i] >> C[i];
    add(A[i], C[i]);
    add(B[i], C[i]);
  }
  for (int i = 0; i < M; i++) {
    cin >> D[i] >> E[i] >> F[i];
    add(D[i], E[i]);
    add(D[i], F[i]);
  }
  xs = compress(xs);
  ys = compress(ys);
  auto find_x = [&](int a) -> int {
    return upper_bound(xs.begin(), xs.end(), a) - xs.begin() - 1;
  };
  auto find_y = [&](int a) -> int {
    return upper_bound(ys.begin(), ys.end(), a) - ys.begin() - 1;
  };

  int xsz = xs.size(), ysz = ys.size();
  bitset<6100> under[6100], right[6100];
  for (int i = 0; i < N; i++) {
    A[i] = find_x(A[i]);
    B[i] = find_x(B[i]);
    C[i] = find_y(C[i]);
    for (int x = A[i] + 1; x <= B[i]; x++)
      right[x][C[i]] = 1;
  }
  for (int i = 0; i < M; i++) {
    D[i] = find_x(D[i]);
    E[i] = find_y(E[i]);
    F[i] = find_y(F[i]);
    for (int y = E[i] + 1; y <= F[i]; y++)
      under[D[i]][y] = 1;
  }
  auto encode = [&](int i, int j) { return i * ysz + j; };
  UnionFind uf(xsz * ysz);
  for (int i = 0; i < xsz - 1; i++)
    for (int j = 0; j < ysz - 1; j++) {
      if (!under[i][j])
        uf.unite(encode(i, j), encode(i + 1, j));
      if (!right[i][j])
        uf.unite(encode(i, j), encode(i, j + 1));
    }

  auto fail = []() {
    cout << "INF" << endl;
    exit(0);
  };
  int cow = encode(find_x(0), find_y(0));
  int64_t ans = 0;
  for (int i = 0; i < xsz; i++)
    for (int j = 0; j < ysz; j++)
      if (uf.same(cow, encode(i, j))) {
        if (i == 0 || i == xsz - 1 || j == 0 || j == ysz - 1)
          fail();
        int64_t dx = xs[i + 1] - xs[i], dy = ys[j + 1] - ys[j];
        ans += dx * dy;
      }
  cout << ans << endl;
  return 0;
}