Problem p02680 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <vector>

using namespace std;
typedef long long ll;

#define rep(i, n) for (ll i = 0; i < (n); i++)
#define reps(i, f, n) for (ll i = (f); i < (n); i++)
#define repr(i, n) for (ll i = n; i >= 0; i--)
#define repv(v) for (auto it = (v).begin(); it != (v).end(); it++)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define INIT                                                                   \
  cin.tie(0);                                                                  \
  ios::sync_with_stdio(false);

template <class T> inline bool chmax(T &a, T b) { return a = (a < b) ? b : a; }
template <class T> inline bool chmin(T &a, T b) { return a = (a > b) ? b : a; }

ll const INF = 1LL << 60;
ll const MOD = 1000000007;

const ll MAX_X = 1010;
const ll MAX_Y = 1010;
ll v_line[MAX_X][MAX_Y];
ll h_line[MAX_X][MAX_Y];
bool vis[MAX_X][MAX_Y];
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};

int main() {
  INIT;

  ll N, M;
  cin >> N >> M;

  vector<ll> A(N), B(N), C(N), D(M), E(M), F(M);
  rep(i, N) { cin >> A[i] >> B[i] >> C[i]; }
  rep(i, M) { cin >> D[i] >> E[i] >> F[i]; }

  // 座標圧縮
  vector<ll> x_dict, y_dict;
  x_dict.pb(-INF);
  x_dict.pb(INF);
  x_dict.pb(0);
  y_dict.pb(-INF);
  y_dict.pb(INF);
  y_dict.pb(0);

  rep(i, N) {
    x_dict.pb(A[i]);
    x_dict.pb(B[i]);
    y_dict.pb(C[i]);
  }

  rep(i, M) {
    x_dict.pb(D[i]);
    y_dict.pb(E[i]);
    y_dict.pb(F[i]);
  }

  sort(ALL(x_dict));
  x_dict.erase(unique(ALL(x_dict)), x_dict.end());
  sort(ALL(y_dict));
  y_dict.erase(unique(ALL(y_dict)), y_dict.end());

  // repv(x_dict) { cout << *it << " "; }
  // cout << endl;
  // repv(y_dict) { cout << *it << " "; }
  // cout << endl;

  ll W = SZ(x_dict);
  ll H = SZ(y_dict);

  // imos法による線分の判定
  rep(i, N) {
    int a = lower_bound(ALL(x_dict), A[i]) - x_dict.begin();
    int b = lower_bound(ALL(x_dict), B[i]) - x_dict.begin();
    int c = lower_bound(ALL(y_dict), C[i]) - y_dict.begin();

    // cout << "(" << A[i] << " -> " << B[i] << ", " << C[i] << ") = (" << a
    //      << " -> " << b << ", " << c << ")" << endl;
    v_line[c][a]++;
    v_line[c][b]--;
  }

  // cout << "----" << endl;
  rep(i, M) {
    int d = lower_bound(ALL(x_dict), D[i]) - x_dict.begin();
    int e = lower_bound(ALL(y_dict), E[i]) - y_dict.begin();
    int f = lower_bound(ALL(y_dict), F[i]) - y_dict.begin();

    // cout << "(" << D[i] << ", " << E[i] << " -> " << F[i] << ") = (" << d
    //      << ", " << e << " -> " << f << ")" << endl;

    h_line[e][d]++;
    h_line[f][d]--;
  }

  rep(y, H) reps(x, 1, W) v_line[y][x] += v_line[y][x - 1];
  rep(x, W) reps(y, 1, H) h_line[y][x] += h_line[y - 1][x];

  // cout << "----" << endl;
  // rep(y, H) {
  //     reps(x, 1, W) { cout << (v_line[y][x] == 1 ? '#' : '.') << " "; }
  //     cout << endl;
  // }

  // cout << "----" << endl;
  // rep(y, H) {
  //     reps(x, 1, W) { cout << (h_line[y][x] == 1 ? '#' : '.') << " "; }
  //     cout << endl;
  // }

  // 座標圧縮により、x_dict, y_dictのindexを座標と再定義できる
  // - 実際の面積を求めたい場合は、idx値から各dictの要素にアクセスし、
  // - 前後の値を引くことにより面積を計算する

  ll res = 0;
  queue<pair<ll, ll>> que;

  ll stx = lower_bound(ALL(x_dict), 0) - x_dict.begin();
  ll sty = lower_bound(ALL(y_dict), 0) - y_dict.begin();

  vis[sty][stx] = true;
  que.push({stx, sty});

  while (!que.empty()) {
    ll ix, iy;
    tie(ix, iy) = que.front();
    que.pop();

    if (ix == 0 || ix == W - 1) {
      res = INF;
      break;
    }
    if (iy == 0 || iy == H - 1) {
      res = INF;
      break;
    }

    res += (x_dict[ix + 1] - x_dict[ix]) * (y_dict[iy + 1] - y_dict[iy]);

    rep(d, 4) {
      ll ix2 = ix + dx[d];
      ll iy2 = iy + dy[d];

      if (0 <= ix2 && ix2 < W && 0 <= iy2 && iy2 < H && !vis[iy2][ix2]) {
        if (ix == ix2) {
          if (v_line[max(iy, iy2)][ix2])
            continue;
        } else {
          if (h_line[iy][max(ix, ix2)])
            continue;
        }

        vis[iy2][ix2] = true;
        que.push({ix2, iy2});
      }
    }
  }

  if (res == INF)
    cout << "INF" << endl;
  else
    cout << res << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <vector>

using namespace std;
typedef long long ll;

#define rep(i, n) for (ll i = 0; i < (n); i++)
#define reps(i, f, n) for (ll i = (f); i < (n); i++)
#define repr(i, n) for (ll i = n; i >= 0; i--)
#define repv(v) for (auto it = (v).begin(); it != (v).end(); it++)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define INIT                                                                   \
  cin.tie(0);                                                                  \
  ios::sync_with_stdio(false);

template <class T> inline bool chmax(T &a, T b) { return a = (a < b) ? b : a; }
template <class T> inline bool chmin(T &a, T b) { return a = (a > b) ? b : a; }

ll const INF = 1LL << 60;
ll const MOD = 1000000007;

const ll MAX_X = 5010;
const ll MAX_Y = 5010;
ll v_line[MAX_X][MAX_Y];
ll h_line[MAX_X][MAX_Y];
bool vis[MAX_X][MAX_Y];
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};

int main() {
  INIT;

  ll N, M;
  cin >> N >> M;

  vector<ll> A(N), B(N), C(N), D(M), E(M), F(M);
  rep(i, N) { cin >> A[i] >> B[i] >> C[i]; }
  rep(i, M) { cin >> D[i] >> E[i] >> F[i]; }

  // 座標圧縮
  vector<ll> x_dict, y_dict;
  x_dict.pb(-INF);
  x_dict.pb(INF);
  x_dict.pb(0);
  y_dict.pb(-INF);
  y_dict.pb(INF);
  y_dict.pb(0);

  rep(i, N) {
    x_dict.pb(A[i]);
    x_dict.pb(B[i]);
    y_dict.pb(C[i]);
  }

  rep(i, M) {
    x_dict.pb(D[i]);
    y_dict.pb(E[i]);
    y_dict.pb(F[i]);
  }

  sort(ALL(x_dict));
  x_dict.erase(unique(ALL(x_dict)), x_dict.end());
  sort(ALL(y_dict));
  y_dict.erase(unique(ALL(y_dict)), y_dict.end());

  // repv(x_dict) { cout << *it << " "; }
  // cout << endl;
  // repv(y_dict) { cout << *it << " "; }
  // cout << endl;

  ll W = SZ(x_dict);
  ll H = SZ(y_dict);

  // imos法による線分の判定
  rep(i, N) {
    int a = lower_bound(ALL(x_dict), A[i]) - x_dict.begin();
    int b = lower_bound(ALL(x_dict), B[i]) - x_dict.begin();
    int c = lower_bound(ALL(y_dict), C[i]) - y_dict.begin();

    // cout << "(" << A[i] << " -> " << B[i] << ", " << C[i] << ") = (" << a
    //      << " -> " << b << ", " << c << ")" << endl;
    v_line[c][a]++;
    v_line[c][b]--;
  }

  // cout << "----" << endl;
  rep(i, M) {
    int d = lower_bound(ALL(x_dict), D[i]) - x_dict.begin();
    int e = lower_bound(ALL(y_dict), E[i]) - y_dict.begin();
    int f = lower_bound(ALL(y_dict), F[i]) - y_dict.begin();

    // cout << "(" << D[i] << ", " << E[i] << " -> " << F[i] << ") = (" << d
    //      << ", " << e << " -> " << f << ")" << endl;

    h_line[e][d]++;
    h_line[f][d]--;
  }

  rep(y, H) reps(x, 1, W) v_line[y][x] += v_line[y][x - 1];
  rep(x, W) reps(y, 1, H) h_line[y][x] += h_line[y - 1][x];

  // cout << "----" << endl;
  // rep(y, H) {
  //     reps(x, 1, W) { cout << (v_line[y][x] == 1 ? '#' : '.') << " "; }
  //     cout << endl;
  // }

  // cout << "----" << endl;
  // rep(y, H) {
  //     reps(x, 1, W) { cout << (h_line[y][x] == 1 ? '#' : '.') << " "; }
  //     cout << endl;
  // }

  // 座標圧縮により、x_dict, y_dictのindexを座標と再定義できる
  // - 実際の面積を求めたい場合は、idx値から各dictの要素にアクセスし、
  // - 前後の値を引くことにより面積を計算する

  ll res = 0;
  queue<pair<ll, ll>> que;

  ll stx = lower_bound(ALL(x_dict), 0) - x_dict.begin();
  ll sty = lower_bound(ALL(y_dict), 0) - y_dict.begin();

  vis[sty][stx] = true;
  que.push({stx, sty});

  while (!que.empty()) {
    ll ix, iy;
    tie(ix, iy) = que.front();
    que.pop();

    if (ix == 0 || ix == W - 1) {
      res = INF;
      break;
    }
    if (iy == 0 || iy == H - 1) {
      res = INF;
      break;
    }

    res += (x_dict[ix + 1] - x_dict[ix]) * (y_dict[iy + 1] - y_dict[iy]);

    rep(d, 4) {
      ll ix2 = ix + dx[d];
      ll iy2 = iy + dy[d];

      if (0 <= ix2 && ix2 < W && 0 <= iy2 && iy2 < H && !vis[iy2][ix2]) {
        if (ix == ix2) {
          if (v_line[max(iy, iy2)][ix2])
            continue;
        } else {
          if (h_line[iy][max(ix, ix2)])
            continue;
        }

        vis[iy2][ix2] = true;
        que.push({ix2, iy2});
      }
    }
  }

  if (res == INF)
    cout << "INF" << endl;
  else
    cout << res << endl;
  return 0;
}