Problem p02680 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i, s, e) for (i64(i) = (s); (i) < (e); (i)++)
#define all(x) x.begin(), x.end()

template <class T>
static inline std::vector<T> ndvec(size_t &&n, T val) noexcept {
  return std::vector<T>(n, std::forward<T>(val));
}

template <class... Tail>
static inline auto ndvec(size_t &&n, Tail &&...tail) noexcept {
  return std::vector<decltype(ndvec(std::forward<Tail>(tail)...))>(
      n, ndvec(std::forward<Tail>(tail)...));
}

template <class T, class Cond> struct chain {
  Cond cond;
  chain(Cond cond) : cond(cond) {}
  bool operator()(T &a, const T &b) const {
    if (cond(a, b)) {
      a = b;
      return true;
    }
    return false;
  }
};
template <class T, class Cond> chain<T, Cond> make_chain(Cond cond) {
  return chain<T, Cond>(cond);
}

#include <tuple>
#include <vector>

struct union_find {
  std::vector<int> par;
  union_find(int N) : par(N, -1) {}
  int root(int x) { return par[x] < 0 ? x : par[x] = root(par[x]); }
  std::tuple<int, int> unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return {-1, -1};
    if (par[x] > par[y])
      std::swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return {x, y};
  }
  int size(int x) { return -par[root(x)]; }
};

int main() {
  i64 N, M;
  cin >> N >> M;

  std::vector<i64> X, Y;
  X.push_back(1e18);
  X.push_back(-1e18);
  Y.push_back(1e18);
  Y.push_back(-1e18);
  X.push_back(0);
  Y.push_back(0);
  std::vector<i64> A(N), B(N), C(N);
  rep(i, 0, N) {
    cin >> A[i] >> B[i] >> C[i];
    X.push_back(A[i]);
    X.push_back(B[i]);
    Y.push_back(C[i]);
  }
  std::vector<i64> D(M), E(M), F(M);
  rep(i, 0, M) {
    cin >> D[i] >> E[i] >> F[i];
    X.push_back(D[i]);
    Y.push_back(E[i]);
    Y.push_back(F[i]);
  }
  sort(all(X));
  sort(all(Y));
  X.erase(unique(all(X)), end(X));
  Y.erase(unique(all(Y)), end(Y));
  std::vector<std::vector<int>> Yline(Y.size(), std::vector<int>(X.size()));
  std::vector<std::vector<int>> Xline(X.size(), std::vector<int>(Y.size()));
  auto index = [](const std::vector<i64> &A, i64 x) {
    return lower_bound(all(A), x) - begin(A);
  };
  rep(i, 0, N) {
    i64 a = index(X, A[i]);
    i64 b = index(X, B[i]);
    i64 y = index(Y, C[i]);
    rep(j, a, b) { Yline[y][j] = true; }
  }
  rep(i, 0, M) {
    i64 x = index(X, D[i]);
    i64 a = index(Y, E[i]);
    i64 b = index(Y, F[i]);
    rep(j, a, b) { Xline[x][j] = true; }
  }

  vector<i64> sz(X.size() * Y.size());
  i64 I = X.size();
  i64 J = Y.size();
  union_find uf(I * J);

  auto add = [](i64 a, i64 b) {
    if (a == -1)
      return -1ll;
    if (b == -1)
      return -1ll;
    return a + b;
  };

  rep(i, 0, I) {
    rep(j, 0, J) {

      if (i == 0 || j == 0 || i + 1 >= I - 1 || j + 1 >= J - 1) {
        sz[i * J + j] = -1;
      } else {
        sz[i * J + j] = (X[i + 1] - X[i]) * (Y[j + 1] - Y[j]);
      }
      // std::cout << sz[i * J + j] << " ";
    }
    // std::cout << endl;
  }
  rep(i, 0, I) {
    rep(j, 0, J) {
      if (0 < i && Xline[i][j] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, (i - 1) * J + j);
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
          sz[c] = 0;
        }
      }
      if (i + 1 < I && Xline[i + 1][j] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, (i + 1) * J + j);
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
          sz[c] = 0;
        }
      }
      if (0 < j && Yline[j][i] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, i * J + (j - 1));
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
          sz[c] = 0;
        }
      }
      if (j + 1 < J && Yline[j + 1][i] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, i * J + j + 1);
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
          sz[c] = 0;
        }
      }
    }
  }
  auto s = index(X, 0ll) * J + index(Y, 0ll);

  if (sz[uf.root(s)] == -1) {
    cout << "INF" << endl;
  } else {
    cout << sz[uf.root(s)] << endl;
  }
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i, s, e) for (i64(i) = (s); (i) < (e); (i)++)
#define all(x) x.begin(), x.end()

template <class T>
static inline std::vector<T> ndvec(size_t &&n, T val) noexcept {
  return std::vector<T>(n, std::forward<T>(val));
}

template <class... Tail>
static inline auto ndvec(size_t &&n, Tail &&...tail) noexcept {
  return std::vector<decltype(ndvec(std::forward<Tail>(tail)...))>(
      n, ndvec(std::forward<Tail>(tail)...));
}

template <class T, class Cond> struct chain {
  Cond cond;
  chain(Cond cond) : cond(cond) {}
  bool operator()(T &a, const T &b) const {
    if (cond(a, b)) {
      a = b;
      return true;
    }
    return false;
  }
};
template <class T, class Cond> chain<T, Cond> make_chain(Cond cond) {
  return chain<T, Cond>(cond);
}

#include <tuple>
#include <vector>

struct union_find {
  std::vector<int> par;
  union_find(int N) : par(N, -1) {}
  int root(int x) { return par[x] < 0 ? x : par[x] = root(par[x]); }
  std::tuple<int, int> unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return {-1, -1};
    if (par[x] > par[y])
      std::swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return {x, y};
  }
  int size(int x) { return -par[root(x)]; }
};

int main() {
  i64 N, M;
  cin >> N >> M;

  std::vector<i64> X, Y;
  X.push_back(1e18);
  X.push_back(-1e18);
  Y.push_back(1e18);
  Y.push_back(-1e18);
  X.push_back(0);
  Y.push_back(0);
  std::vector<i64> A(N), B(N), C(N);
  rep(i, 0, N) {
    cin >> A[i] >> B[i] >> C[i];
    X.push_back(A[i]);
    X.push_back(B[i]);
    Y.push_back(C[i]);
  }
  std::vector<i64> D(M), E(M), F(M);
  rep(i, 0, M) {
    cin >> D[i] >> E[i] >> F[i];
    X.push_back(D[i]);
    Y.push_back(E[i]);
    Y.push_back(F[i]);
  }
  sort(all(X));
  sort(all(Y));
  X.erase(unique(all(X)), end(X));
  Y.erase(unique(all(Y)), end(Y));
  std::vector<std::vector<int>> Yline(Y.size(), std::vector<int>(X.size()));
  std::vector<std::vector<int>> Xline(X.size(), std::vector<int>(Y.size()));
  auto index = [](const std::vector<i64> &A, i64 x) {
    return lower_bound(all(A), x) - begin(A);
  };
  rep(i, 0, N) {
    i64 a = index(X, A[i]);
    i64 b = index(X, B[i]);
    i64 y = index(Y, C[i]);
    rep(j, a, b) { Yline[y][j] = true; }
  }
  rep(i, 0, M) {
    i64 x = index(X, D[i]);
    i64 a = index(Y, E[i]);
    i64 b = index(Y, F[i]);
    rep(j, a, b) { Xline[x][j] = true; }
  }

  vector<i64> sz(X.size() * Y.size());
  i64 I = X.size();
  i64 J = Y.size();
  union_find uf(I * J);

  auto add = [](i64 a, i64 b) {
    if (a == -1)
      return -1ll;
    if (b == -1)
      return -1ll;
    return a + b;
  };

  rep(i, 0, I) {
    rep(j, 0, J) {

      if (i == 0 || j == 0 || i + 1 >= I - 1 || j + 1 >= J - 1) {
        sz[i * J + j] = -1;
      } else {
        sz[i * J + j] = (X[i + 1] - X[i]) * (Y[i + 1] - Y[i]);
      }
      // std::cout << sz[i * J + j] << " ";
    }
    // std::cout << endl;
  }
  rep(i, 0, I) {
    rep(j, 0, J) {
      if (0 < i && Xline[i][j] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, (i - 1) * J + j);
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
        }
      }
      if (i + 1 < I && Xline[i + 1][j] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, (i + 1) * J + j);
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
        }
      }
      if (0 < j && Yline[j][i] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, i * J + (j - 1));
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
        }
      }
      if (j + 1 < J && Yline[j + 1][i] == false) {
        int r, c;
        std::tie(r, c) = uf.unite(i * J + j, i * J + j + 1);
        if (r != -1) {
          sz[r] = add(sz[r], sz[c]);
        }
      }
    }
  }

  auto s = index(X, 0ll) * J + index(Y, 0ll);

  if (sz[uf.root(s)] == -1) {
    cout << "INF" << endl;
    assert(false);
  } else {
    cout << sz[uf.root(s)] << endl;
  }
}