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

// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;

template <typename T> bool chmin(T &x, T y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}

template <typename T> bool chmax(T &x, T y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}

template <typename T> struct Compression {
  vector<T> compvec;
  unordered_map<T, int> th;
  Compression(vector<T> &inp) { // 圧縮する
    compvec = inp;
    sort(compvec.begin(), compvec.end());
    compvec.erase(unique(compvec.begin(), compvec.end()), compvec.end());
  }
  int Index(T val) { // 圧縮を元に対応するインデックスを返す
    if (th.find(val) != th.end())
      return th[val];
    auto it = lower_bound(compvec.begin(), compvec.end(), val);
    return th[val] = distance(compvec.begin(), it);
  }
  vector<T> &operator*() { return compvec; }
};

struct UnionFind {
  vector<int> par;
  int count;
  UnionFind(int n) : par(n, -1), count(0) {}
  int Find(int x) { return par[x] < 0 ? x : Find(par[x]); }
  int Size(int x) { return par[x] < 0 ? -par[x] : Size(par[x]); }
  bool Unite(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return ++count;
  }
};

void solve(long long n, long long m, std::vector<long long> a,
           std::vector<long long> b, std::vector<long long> c,
           std::vector<long long> d, std::vector<long long> e,
           std::vector<long long> f) {
  vector<int> ccx{0, 1, -1, MOD, MOD + 1, -MOD, -MOD - 1};
  vector<int> ccy{0, 1, -1, MOD, MOD + 1, -MOD, -MOD - 1};
  for (int i = 0; i < n; ++i) {
    ccx.emplace_back(a[i]);
    ccx.emplace_back(b[i]);
    ccy.emplace_back(c[i]);
  }
  for (int i = 0; i < m; ++i) {
    ccy.emplace_back(e[i]);
    ccy.emplace_back(f[i]);
    ccx.emplace_back(d[i]);
  }
  Compression<int> cx(ccx);
  Compression<int> cy(ccy);

  UnionFind uf((*cx).size() * (*cy).size());

  auto idx = [&](int i, int j) { return i * (*cy).size() + j; };

  set<pair<pair<int, int>, pair<int, int>>> ign;
  for (int i = 0; i < n; ++i) {
    int sx = cx.Index(a[i]);
    int ex = cx.Index(b[i]);
    int y = cy.Index(c[i]);
    for (int x = sx; x < ex; ++x)
      ign.emplace(minmax(make_pair(x, y - 1), make_pair(x, y)));
  }
  for (int i = 0; i < m; ++i) {
    int x = cx.Index(d[i]);
    int sy = cy.Index(e[i]);
    int ey = cy.Index(f[i]);
    for (int y = sy; y < ey; ++y)
      ign.emplace(minmax(make_pair(x - 1, y), make_pair(x, y)));
  }

  for (int i = 0; i < (*cx).size(); ++i) {
    for (int j = 0; j < (*cy).size(); ++j) {
      auto p = make_pair(i, j);
      auto p1 = make_pair(i + 1, j);
      auto p2 = make_pair(i, j + 1);
      if (i + 1 != (*cx).size() && ign.find(minmax(p, p1)) == ign.end())
        uf.Unite(idx(i, j), idx(i + 1, j));
      if (j + 1 != (*cy).size() && ign.find(minmax(p, p2)) == ign.end())
        uf.Unite(idx(i, j), idx(i, j + 1));
    }
  }

  int id = idx(cx.Index(0), cy.Index(0));
  int uid = uf.Find(id);
  if (uid == uf.Find(0)) {
    cout << "INF" << endl;
    return;
  }
  i64 ans = 0;
  for (int i = 0; i < (*cx).size(); ++i) {
    for (int j = 0; j < (*cy).size(); ++j) {
      if (uf.Find(idx(i, j)) == uid) {
        if (i + 1 == (*cx).size() || j + 1 == (*cy).size()) {
          cout << "INF" << endl;
          return;
        }
        i64 xd = (*cx)[i + 1] - (*cx)[i];
        i64 yd = (*cy)[j + 1] - (*cy)[j];
        ans += xd * yd;
      }
    }
  }
  cout << ans << endl;
}

signed main() {
  long long N;
  scanf("%lld", &N);
  long long M;
  scanf("%lld", &M);
  std::vector<long long> A(N);
  std::vector<long long> B(N);
  std::vector<long long> C(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &A[i]);
    scanf("%lld", &B[i]);
    scanf("%lld", &C[i]);
  }
  std::vector<long long> D(M);
  std::vector<long long> E(M);
  std::vector<long long> F(M);
  for (int i = 0; i < M; i++) {
    scanf("%lld", &D[i]);
    scanf("%lld", &E[i]);
    scanf("%lld", &F[i]);
  }
  solve(N, M, std::move(A), std::move(B), std::move(C), std::move(D),
        std::move(E), std::move(F));
  return 0;
}


Error: TLE

Fixed submission:

// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;

template <typename T> bool chmin(T &x, T y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}

template <typename T> bool chmax(T &x, T y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}

template <typename T> struct Compression {
  vector<T> compvec;
  unordered_map<T, int> th;
  Compression(vector<T> &inp) { // 圧縮する
    compvec = inp;
    sort(compvec.begin(), compvec.end());
    compvec.erase(unique(compvec.begin(), compvec.end()), compvec.end());
  }
  int Index(T val) { // 圧縮を元に対応するインデックスを返す
    if (th.find(val) != th.end())
      return th[val];
    auto it = lower_bound(compvec.begin(), compvec.end(), val);
    return th[val] = distance(compvec.begin(), it);
  }
  vector<T> &operator*() { return compvec; }
};

struct UnionFind {
  vector<int> par;
  int count;
  UnionFind(int n) : par(n, -1), count(0) {}
  int Find(int x) { return par[x] < 0 ? x : Find(par[x]); }
  int Size(int x) { return par[x] < 0 ? -par[x] : Size(par[x]); }
  bool Unite(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return ++count;
  }
};

void solve(long long n, long long m, std::vector<long long> a,
           std::vector<long long> b, std::vector<long long> c,
           std::vector<long long> d, std::vector<long long> e,
           std::vector<long long> f) {
  vector<int> ccx{0, 1, -1, MOD, MOD + 1, -MOD, -MOD - 1};
  vector<int> ccy{0, 1, -1, MOD, MOD + 1, -MOD, -MOD - 1};
  for (int i = 0; i < n; ++i) {
    ccx.emplace_back(a[i]);
    ccx.emplace_back(b[i]);
    ccx.emplace_back(a[i] + 1);
    ccx.emplace_back(b[i] + 1);
    ccx.emplace_back(a[i] - 1);
    ccx.emplace_back(b[i] - 1);
    ccy.emplace_back(c[i]);
    ccy.emplace_back(c[i] + 1);
    ccy.emplace_back(c[i] - 1);
  }
  for (int i = 0; i < m; ++i) {
    ccy.emplace_back(e[i]);
    ccy.emplace_back(f[i]);
    ccy.emplace_back(e[i] + 1);
    ccy.emplace_back(f[i] + 1);
    ccy.emplace_back(e[i] - 1);
    ccy.emplace_back(f[i] - 1);
    ccx.emplace_back(d[i]);
    ccx.emplace_back(d[i] + 1);
    ccx.emplace_back(d[i] - 1);
  }
  Compression<int> cx(ccx);
  Compression<int> cy(ccy);

  UnionFind uf((*cx).size() * (*cy).size());

  auto idx = [&](int i, int j) { return i * (*cy).size() + j; };

  set<pair<pair<int, int>, pair<int, int>>> ign;
  for (int i = 0; i < n; ++i) {
    int sx = cx.Index(a[i]);
    int ex = cx.Index(b[i]);
    int y = cy.Index(c[i]);
    for (int x = sx; x < ex; ++x)
      ign.emplace(minmax(make_pair(x, y - 1), make_pair(x, y)));
  }
  for (int i = 0; i < m; ++i) {
    int x = cx.Index(d[i]);
    int sy = cy.Index(e[i]);
    int ey = cy.Index(f[i]);
    for (int y = sy; y < ey; ++y)
      ign.emplace(minmax(make_pair(x - 1, y), make_pair(x, y)));
  }

  for (int i = 0; i < (*cx).size(); ++i) {
    for (int j = 0; j < (*cy).size(); ++j) {
      auto p = make_pair(i, j);
      auto p1 = make_pair(i + 1, j);
      auto p2 = make_pair(i, j + 1);
      if (i + 1 != (*cx).size() && ign.find(minmax(p, p1)) == ign.end())
        uf.Unite(idx(i, j), idx(i + 1, j));
      if (j + 1 != (*cy).size() && ign.find(minmax(p, p2)) == ign.end())
        uf.Unite(idx(i, j), idx(i, j + 1));
    }
  }

  int id = idx(cx.Index(0), cy.Index(0));
  int uid = uf.Find(id);
  if (uid == uf.Find(0)) {
    cout << "INF" << endl;
    return;
  }
  i64 ans = 0;
  for (int i = 0; i < (*cx).size(); ++i) {
    for (int j = 0; j < (*cy).size(); ++j) {
      if (uf.Find(idx(i, j)) == uid) {
        if (i + 1 == (*cx).size() || j + 1 == (*cy).size()) {
          cout << "INF" << endl;
          return;
        }
        i64 xd = (*cx)[i + 1] - (*cx)[i];
        i64 yd = (*cy)[j + 1] - (*cy)[j];
        ans += xd * yd;
      }
    }
  }
  cout << ans << endl;
}

signed main() {
  long long N;
  scanf("%lld", &N);
  long long M;
  scanf("%lld", &M);
  std::vector<long long> A(N);
  std::vector<long long> B(N);
  std::vector<long long> C(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &A[i]);
    scanf("%lld", &B[i]);
    scanf("%lld", &C[i]);
  }
  std::vector<long long> D(M);
  std::vector<long long> E(M);
  std::vector<long long> F(M);
  for (int i = 0; i < M; i++) {
    scanf("%lld", &D[i]);
    scanf("%lld", &E[i]);
    scanf("%lld", &F[i]);
  }
  solve(N, M, std::move(A), std::move(B), std::move(C), std::move(D),
        std::move(E), std::move(F));
  return 0;
}