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

#include <bits/stdc++.h>
#ifdef LOCAL_DEBUG
#define DEBUG 1
#define CERR                                                                   \\
  if (DEBUG)                                                                   \\
  cerr
#define MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
#define pr(...)                                                                \\
  CERR << MACRO(__VA_ARGS__, pr10, pr9, pr8, pr7, pr6, pr5, pr4, pr3, pr2,     \\
                pr1)(__VA_ARGS__)                                              \\
       << endl
#define pr1(a) (#a) << "=" << (a) << " "
#define pr2(a, b) pr1(a) << pr1(b)
#define pr3(a, b, c) pr1(a) << pr2(b, c)
#define pr4(a, b, c, d) pr1(a) << pr3(b, c, d)
#define pr5(a, b, c, d, e) pr1(a) << pr4(b, c, d, e)
#define pr6(a, b, c, d, e, f) pr1(a) << pr5(b, c, d, e, f)
#define pr7(a, b, c, d, e, f, g) pr1(a) << pr6(b, c, d, e, f, g)
#define pr8(a, b, c, d, e, f, g, h) pr1(a) << pr7(b, c, d, e, f, g, h)
#define pr9(a, b, c, d, e, f, g, h, i) pr1(a) << pr8(b, c, d, e, f, g, h, i)
#define pr10(a, b, c, d, e, f, g, h, i, j)                                     \\
  pr1(a) << pr9(b, c, d, e, f, g, h, i, j)
#define prArr(a)                                                               \\
  {                                                                            \\
    CERR << (#a) << "={";                                                      \\
    int i = 0;                                                                 \\
    for (auto t : (a))                                                         \\
      CERR << (i++ ? ", " : "") << t;                                          \\
    CERR << "}" << endl;                                                       \\
  }
#else
#define DEBUG 0
#define pr(...)
#define prArr(a)
#endif
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL << 60) + 1e9; // ~ 1.15 * 1e18
const Int mod = (1e9) + 7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int, Int>;
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
template <class T1, class T2> ostream &operator<<(ostream &o, pair<T1, T2> p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <class T1, class T2, class T3>
ostream &operator<<(ostream &o, tuple<T1, T2, T3> t) {
  return o << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")";
}
template <class T1, class T2> istream &operator>>(istream &i, pair<T1, T2> &p) {
  return i >> p.first >> p.second;
}
template <class T> ostream &operator<<(ostream &o, vector<T> a) {
  Int i = 0;
  for (T t : a)
    o << (i++ ? " " : "") << t;
  return o;
}
template <class T> istream &operator>>(istream &i, vector<T> &a) {
  for (T &t : a)
    i >> t;
  return i;
}
// INSERT ABOVE HERE

template <typename T> class Compress {
public:
  vector<T> X;
  bool ok;
  Compress() : ok(false){};

  Int size() {
    assert(ok);
    return X.size();
  }
  void add(T a) {
    ok = false;
    X.push_back(a);
    X.push_back(a - 1);
    X.push_back(a + 1);
  }
  // void add(T a){ok = false; X.push_back(a);}// X.push_back(a-1);
  // X.push_back(a+1);}
  void add(const vector<T> a) {
    for (T x : a)
      add(x);
  }
  // void add(const vector<T> &a){for(T x:a) add(x);}

  void build() {
    ok = true;
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
  }

  Int getL(T x) {
    assert(ok);
    return lower_bound(X.begin(), X.end(), x) - X.begin();
  }
  Int getU(T x) {
    assert(ok);
    return upper_bound(X.begin(), X.end(), x) - X.begin();
  }
};

signed main() {
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  Int N, M;
  cin >> N >> M;
  using PP = pair<P, P>;
  vector<PP> A;

  Compress<Int> X, Y;
  Int T = 2;
  for (Int i = 0; i < N; i++) {
    Int a, b, c;
    cin >> a >> b >> c;
    a *= T, b *= T, c *= T;
    A.push_back(PP(P(a, c), P(b, c)));
    X.add(a);
    X.add(b);
    Y.add(c);
  }

  for (Int i = 0; i < M; i++) {
    Int d, e, f;
    cin >> d >> e >> f;
    d *= T, e *= T, f *= T;
    A.push_back(PP(P(d, e), P(d, f)));
    X.add(d);
    Y.add(e);
    Y.add(f);
  }
  X.add(-INF);
  X.add(INF);
  Y.add(-INF);
  Y.add(INF);

  X.build();
  Y.build();
  auto get = [&](Int x, Int y) { return P(X.getL(x), Y.getL(y)); };

  Int H = Y.size();
  Int W = X.size();
  vector<vector<char>> mp1(Y.size() + 1, vector<char>(X.size() + 1, 0));
  vector<vector<char>> mp2(Y.size() + 1, vector<char>(X.size() + 1, 0));
  for (auto v : A) {
    Int x, y;
    tie(x, y) = v.first;
    Int a, b;
    tie(a, b) = v.second;
    tie(x, y) = get(x, y);
    tie(a, b) = get(a, b);
    if (x != a && y == b) {
      assert(x < a);
      mp1[y][x]++;
      mp1[y][a + 1]--;
    }
    if (x == a && y != b) {
      assert(y < b);
      mp2[y][x]++;
      mp2[b + 1][x]--;
    }
  }

  for (Int i = 0; i <= H; i++)
    for (Int j = 1; j < W; j++)
      mp1[i][j] += mp1[i][j - 1];

  for (Int i = 0; i <= W; i++)
    for (Int j = 1; j < H; j++)
      mp2[j][i] += mp2[j - 1][i];

  Int ox, oy;
  tie(ox, oy) = get(0, 0);
  // mp[oy][ox] = 5;
  // for(Int i=0;i<H;i++) pr(mp[i]);
  // mp[oy][ox] = 0;

  vector<vector<char>> visited(Y.size(), vector<char>(X.size(), 0));
  queue<P> Q;
  Q.push(P(ox, oy));
  visited[oy][ox] = 1;
  __int128_t ans = 0;
  while (!Q.empty()) {
    Int x, y;
    tie(x, y) = Q.front();
    Q.pop();
    // if(visited[y][x]) continue;
    // visited[y][x] = 1;
    {
      __int128_t a = X.X[x + 1] - X.X[x];
      __int128_t b = Y.X[y + 1] - Y.X[y];
      ans += a * b;
    }

    const Int dx[] = {0, 0, 1, -1};
    const Int dy[] = {1, -1, 0, 0};
    for (Int i = 0; i < 4; i++) {
      if (mp1[y][x] && (i == 0 || i == 1))
        continue; // 横線に対して縦に移動しない
      if (mp2[y][x] && (i == 2 || i == 3))
        continue; // 縦線に対して横に移動しない
      Int nx = x + dx[i];
      Int ny = y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (visited[ny][nx])
        continue;
      if (i == 2 && (mp2[ny][nx]))
        continue; // 右にいくときに縦線
      if (i == 0 && (mp1[ny][nx]))
        continue; // 下にいくときに横線
      visited[ny][nx] = 1;
      Q.push(P(nx, ny));
    }
  }

  if (visited[0][0] || visited[H - 1][0] || visited[0][W - 1] ||
      visited[H - 1][W - 1]) {
    cout << "INF" << endl;
    return 0;
  }
  assert(ans % (T * T) == 0);
  ans /= T * T;
  cout << (Int)ans << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#ifdef LOCAL_DEBUG
#define DEBUG 1
#define CERR                                                                   \\
  if (DEBUG)                                                                   \\
  cerr
#define MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
#define pr(...)                                                                \\
  CERR << MACRO(__VA_ARGS__, pr10, pr9, pr8, pr7, pr6, pr5, pr4, pr3, pr2,     \\
                pr1)(__VA_ARGS__)                                              \\
       << endl
#define pr1(a) (#a) << "=" << (a) << " "
#define pr2(a, b) pr1(a) << pr1(b)
#define pr3(a, b, c) pr1(a) << pr2(b, c)
#define pr4(a, b, c, d) pr1(a) << pr3(b, c, d)
#define pr5(a, b, c, d, e) pr1(a) << pr4(b, c, d, e)
#define pr6(a, b, c, d, e, f) pr1(a) << pr5(b, c, d, e, f)
#define pr7(a, b, c, d, e, f, g) pr1(a) << pr6(b, c, d, e, f, g)
#define pr8(a, b, c, d, e, f, g, h) pr1(a) << pr7(b, c, d, e, f, g, h)
#define pr9(a, b, c, d, e, f, g, h, i) pr1(a) << pr8(b, c, d, e, f, g, h, i)
#define pr10(a, b, c, d, e, f, g, h, i, j)                                     \\
  pr1(a) << pr9(b, c, d, e, f, g, h, i, j)
#define prArr(a)                                                               \\
  {                                                                            \\
    CERR << (#a) << "={";                                                      \\
    int i = 0;                                                                 \\
    for (auto t : (a))                                                         \\
      CERR << (i++ ? ", " : "") << t;                                          \\
    CERR << "}" << endl;                                                       \\
  }
#else
#define DEBUG 0
#define pr(...)
#define prArr(a)
#endif
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL << 60) + 1e9; // ~ 1.15 * 1e18
const Int mod = (1e9) + 7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int, Int>;
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
template <class T1, class T2> ostream &operator<<(ostream &o, pair<T1, T2> p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <class T1, class T2, class T3>
ostream &operator<<(ostream &o, tuple<T1, T2, T3> t) {
  return o << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")";
}
template <class T1, class T2> istream &operator>>(istream &i, pair<T1, T2> &p) {
  return i >> p.first >> p.second;
}
template <class T> ostream &operator<<(ostream &o, vector<T> a) {
  Int i = 0;
  for (T t : a)
    o << (i++ ? " " : "") << t;
  return o;
}
template <class T> istream &operator>>(istream &i, vector<T> &a) {
  for (T &t : a)
    i >> t;
  return i;
}
// INSERT ABOVE HERE

template <typename T> class Compress {
public:
  vector<T> X;
  bool ok;
  Compress() : ok(false){};

  Int size() {
    assert(ok);
    return X.size();
  }
  void add(T a) {
    ok = false;
    X.push_back(a);
    X.push_back(a - 1);
    X.push_back(a + 1);
  }
  // void add(T a){ok = false; X.push_back(a);}// X.push_back(a-1);
  // X.push_back(a+1);}
  void add(const vector<T> a) {
    for (T x : a)
      add(x);
  }
  // void add(const vector<T> &a){for(T x:a) add(x);}

  void build() {
    ok = true;
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
  }

  Int getL(T x) {
    assert(ok);
    return lower_bound(X.begin(), X.end(), x) - X.begin();
  }
  Int getU(T x) {
    assert(ok);
    return upper_bound(X.begin(), X.end(), x) - X.begin();
  }
};

signed main() {
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  Int N, M;
  cin >> N >> M;
  using PP = pair<P, P>;
  vector<PP> A;

  Compress<Int> X, Y;
  Int T = 2;
  for (Int i = 0; i < N; i++) {
    Int a, b, c;
    cin >> a >> b >> c;
    a *= T, b *= T, c *= T;
    A.push_back(PP(P(a, c), P(b, c)));
    X.add(a);
    X.add(b);
    Y.add(c);
  }

  for (Int i = 0; i < M; i++) {
    Int d, e, f;
    cin >> d >> e >> f;
    d *= T, e *= T, f *= T;
    A.push_back(PP(P(d, e), P(d, f)));
    X.add(d);
    Y.add(e);
    Y.add(f);
  }
  X.add(-INF);
  X.add(INF);
  Y.add(-INF);
  Y.add(INF);

  X.build();
  Y.build();
  auto get = [&](Int x, Int y) { return P(X.getL(x), Y.getL(y)); };

  Int H = Y.size();
  Int W = X.size();
  vector<vector<char>> mp1(Y.size() + 1, vector<char>(X.size() + 1, 0));
  vector<vector<char>> mp2(Y.size() + 1, vector<char>(X.size() + 1, 0));
  for (auto v : A) {
    Int x, y;
    tie(x, y) = v.first;
    Int a, b;
    tie(a, b) = v.second;
    tie(x, y) = get(x, y);
    tie(a, b) = get(a, b);
    if (x != a && y == b) {
      assert(x < a);
      mp1[y][x]++;
      mp1[y][a + 1]--;
    }
    if (x == a && y != b) {
      assert(y < b);
      mp2[y][x]++;
      mp2[b + 1][x]--;
    }
  }

  for (Int i = 0; i <= H; i++)
    for (Int j = 1; j < W; j++)
      mp1[i][j] += mp1[i][j - 1];

  for (Int i = 0; i <= W; i++)
    for (Int j = 1; j < H; j++)
      mp2[j][i] += mp2[j - 1][i];

  Int ox, oy;
  tie(ox, oy) = get(0, 0);
  // mp[oy][ox] = 5;
  // for(Int i=0;i<H;i++) pr(mp[i]);
  // mp[oy][ox] = 0;

  vector<vector<char>> visited(Y.size(), vector<char>(X.size(), 0));
  queue<P> Q;
  Q.push(P(ox, oy));
  visited[oy][ox] = 1;
  while (!Q.empty()) {
    Int x, y;
    tie(x, y) = Q.front();
    Q.pop();
    // if(visited[y][x]) continue;
    // visited[y][x] = 1;
    Int dx[] = {0, 0, 1, -1};
    Int dy[] = {1, -1, 0, 0};
    for (Int i = 0; i < 4; i++) {
      if (mp1[y][x] && (i == 0 || i == 1))
        continue; // 横線に対して縦に移動しない
      if (mp2[y][x] && (i == 2 || i == 3))
        continue; // 縦線に対して横に移動しない
      Int nx = x + dx[i];
      Int ny = y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (i == 2 && (mp2[ny][nx]))
        continue; // 右にいくときに縦線
      if (i == 0 && (mp1[ny][nx]))
        continue; // 下にいくときに横線
      if (visited[ny][nx])
        continue;
      visited[ny][nx] = 1;
      Q.push(P(nx, ny));
    }
  }

  if (visited[0][0] || visited[H - 1][0] || visited[0][W - 1] ||
      visited[H - 1][W - 1]) {
    cout << "INF" << endl;
    return 0;
  }

  /*
  for(Int i=0;i<H;i++){
  for(Int j=0;j<W;j++){
      cout<<(Int)visited[i][j];
    }
    cout<<endl;
  }
  */

  __int128_t ans = 0;
  for (Int i = 0; i < H; i++)
    for (Int j = 0; j < W; j++) {
      if (visited[i][j] == 0)
        continue;
      __int128_t a = X.X[j + 1] - X.X[j];
      __int128_t b = Y.X[i + 1] - Y.X[i];
      ans += a * b;
    }
  assert(ans % (T * T) == 0);
  ans /= T * T;
  cout << (Int)ans << endl;

  return 0;
}