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

/* coordinate_compress_2D.cpp
    2Dの座標圧縮を行う

    verified: [AOJ] DSL_4_A Union of Rectangles
        http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_4_A&lang=ja
*/

#include <bits/stdc++.h>
using namespace std;
// 1次元 vector
template <class T> ostream &operator<<(ostream &s, vector<T> vec) {
  for (int i = 0; i < (int)vec.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << vec[i];
  }
  return s << endl;
}
template <class T> // 2次元 vector
ostream &operator<<(ostream &s, vector<vector<T>> vec2) {
  for (int i = 0; i < (int)vec2.size(); ++i) {
    s << vec2[i];
  }
  return s;
}
/* compress
    (X1,Y1),(X2,Y2)という二点で表されるもの（長方形や直線など）について、行か列の片方（X1とX2
   or Y1とY2）を座標圧縮する（副作用） 返り値: ソートされ重複要素を除いた値
    計算量: O(n log n)
*/
template <typename T> vector<T> compress(vector<T> &C1, vector<T> &C2) {
  vector<T> vals;
  int N = (int)C1.size();
  for (int i = 0; i < N; i++) {
    T tc1 = C1[i];
    T tc2 = C2[i];
    vals.push_back(tc1);
    vals.push_back(tc2);
  }
  // ソート
  sort(vals.begin(), vals.end());
  // 隣り合う重複を削除(unique), 末端のゴミを削除(erase)
  vals.erase(unique(vals.begin(), vals.end()), vals.end());
  for (int i = 0; i < N; i++) {
    C1[i] = lower_bound(vals.begin(), vals.end(), C1[i]) - vals.begin();
    C2[i] = lower_bound(vals.begin(), vals.end(), C2[i]) - vals.begin();
  }
  return vals;
}

using ll = long long;

int main() {
  int N, M;
  cin >> N >> M;
  vector<long long> X1, Y1, X2, Y2;
  for (int i = 0; i < N; i++) {
    ll a, b, c;
    cin >> a >> b >> c;
    X1.push_back(a);
    X2.push_back(b);
    Y1.push_back(c);
    Y2.push_back(c);
  }
  for (int i = 0; i < M; i++) {
    ll a, b, c;
    cin >> a >> b >> c;
    X1.push_back(a);
    X2.push_back(a);
    Y1.push_back(b);
    Y2.push_back(c);
  }
  // 牛の位置
  X1.push_back(0);
  X2.push_back(0);
  Y1.push_back(0);
  Y2.push_back(0);

  vector<long long> X = compress(X1, X2);
  vector<long long> Y = compress(Y1, Y2);

  int H = X.size() * 2;
  int W = Y.size() * 2;
  vector<vector<int>> G(H, vector<int>(W));
  for (int i = 0; i < N; i++) {
    for (int x = X1[i] * 2; x <= X2[i] * 2; x++) {
      G[x][Y1[i] * 2] = -1;
    }
  }
  for (int i = N; i < N + M; i++) {
    for (int y = Y1[i] * 2; y <= Y2[i] * 2; y++) {
      G[X1[i] * 2][y] = -1;
    }
  }

  using P = pair<int, int>;
  P s(X1[N + M] * 2, Y1[N + M] * 2);
  G[s.first][s.second] = 1;
  // cerr << G;
  queue<pair<int, int>> que;
  que.emplace(s);
  while (que.size() != 0) {
    pair<int, int> now = que.front();
    que.pop();
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1}; // dx,dy は次の探索場所への距離を表す（４方向分）
    for (int i = 0; i < 4; i++) {
      int nx = now.first + dx[i];
      int ny = now.second + dy[i];
      if (nx < 0 || ny < 0 || H <= nx || W <= ny)
        continue;
      if (G[nx][ny] != 0)
        continue; // 障害物があればスルー
      que.push(P(nx, ny));
      G[nx][ny] = 1;
    }
  }

  ll ans = 0;
  for (int x = 0; x < H; x++) {
    for (int y = 0; y < W; y++) {
      if (G[x][y] != 1)
        continue;
      if (x == 0 || H - 1 == x || y == 0 || W - 1 == y) {
        cout << "INF" << endl;
        return 0;
      }
      if (x % 2 == 0 || y % 2 == 0)
        continue;
      ans += (X[x / 2 + 1] - X[x / 2]) * (Y[y / 2 + 1] - Y[y / 2]);
    }
  }

  cout << ans << endl;
}


Error: TLE

Fixed submission:

/* coordinate_compress_2D.cpp
    2Dの座標圧縮を行う

    verified: [AOJ] DSL_4_A Union of Rectangles
        http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_4_A&lang=ja
*/

#include <bits/stdc++.h>
using namespace std;
// 1次元 vector
template <class T> ostream &operator<<(ostream &s, vector<T> vec) {
  for (int i = 0; i < (int)vec.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << vec[i];
  }
  return s << endl;
}
template <class T> // 2次元 vector
ostream &operator<<(ostream &s, vector<vector<T>> vec2) {
  for (int i = 0; i < (int)vec2.size(); ++i) {
    s << vec2[i];
  }
  return s;
}
/* compress
    (X1,Y1),(X2,Y2)という二点で表されるもの（長方形や直線など）について、行か列の片方（X1とX2
   or Y1とY2）を座標圧縮する（副作用） 返り値: ソートされ重複要素を除いた値
    計算量: O(n log n)
*/
template <typename T> vector<T> compress(vector<T> &C1, vector<T> &C2) {
  vector<T> vals;
  int N = (int)C1.size();
  for (int i = 0; i < N; i++) {
    for (
        T d = 0; d <= 1;
        d++) { // その位置と、一つ隣を確保(隣を確保しないと空白が埋まってしまうことがある)
      T tc1 = C1[i] + d;
      T tc2 = C2[i] + d;
      vals.push_back(tc1);
      vals.push_back(tc2);
    }
  }
  // ソート
  sort(vals.begin(), vals.end());
  // 隣り合う重複を削除(unique), 末端のゴミを削除(erase)
  vals.erase(unique(vals.begin(), vals.end()), vals.end());
  for (int i = 0; i < N; i++) {
    C1[i] = lower_bound(vals.begin(), vals.end(), C1[i]) - vals.begin();
    C2[i] = lower_bound(vals.begin(), vals.end(), C2[i]) - vals.begin();
  }
  return vals;
}

using ll = long long;

int main() {
  int N, M;
  cin >> N >> M;
  vector<long long> X1, Y1, X2, Y2;
  for (int i = 0; i < N; i++) {
    ll a, b, c;
    cin >> a >> b >> c;
    X1.push_back(a);
    X2.push_back(b);
    Y1.push_back(c);
    Y2.push_back(c);
  }
  for (int i = 0; i < M; i++) {
    ll a, b, c;
    cin >> a >> b >> c;
    X1.push_back(a);
    X2.push_back(a);
    Y1.push_back(b);
    Y2.push_back(c);
  }
  // 牛の位置
  X1.push_back(0);
  X2.push_back(0);
  Y1.push_back(0);
  Y2.push_back(0);

  vector<long long> X = compress(X1, X2);
  vector<long long> Y = compress(Y1, Y2);

  int H = X.size() * 2;
  int W = Y.size() * 2;
  vector<vector<int>> G(H, vector<int>(W));
  for (int i = 0; i < N; i++) {
    for (int x = X1[i] * 2; x <= X2[i] * 2; x++) {
      G[x][Y1[i] * 2] = -1;
    }
  }
  for (int i = N; i < N + M; i++) {
    for (int y = Y1[i] * 2; y <= Y2[i] * 2; y++) {
      G[X1[i] * 2][y] = -1;
    }
  }

  using P = pair<int, int>;
  P s(X1[N + M] * 2, Y1[N + M] * 2);
  G[s.first][s.second] = 1;
  // cerr << G;
  queue<pair<int, int>> que;
  que.emplace(s);
  while (que.size() != 0) {
    pair<int, int> now = que.front();
    que.pop();
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1}; // dx,dy は次の探索場所への距離を表す（４方向分）
    for (int i = 0; i < 4; i++) {
      int nx = now.first + dx[i];
      int ny = now.second + dy[i];
      if (nx < 0 || ny < 0 || H <= nx || W <= ny)
        continue;
      if (G[nx][ny] != 0)
        continue; // 障害物があればスルー
      que.push(P(nx, ny));
      G[nx][ny] = 1;
    }
  }

  ll ans = 0;
  for (int x = 0; x < H; x++) {
    for (int y = 0; y < W; y++) {
      if (G[x][y] != 1)
        continue;
      if (x == 0 || H - 1 == x || y == 0 || W - 1 == y) {
        cout << "INF" << endl;
        return 0;
      }
      if (x % 2 == 0 || y % 2 == 0)
        continue;
      ans += (X[x / 2 + 1] - X[x / 2]) * (Y[y / 2 + 1] - Y[y / 2]);
    }
  }

  cout << ans << endl;
}