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

// #define _GLIBCXX_DEBUG
// #define _LIBCPP_DEBUG 0

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>    // assert
#include <cmath>      // abs など
#include <functional> // greater など
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric> // accumulate, gcd など
#include <queue>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
typedef long long ll;

//////////////// //////////////// //////////////// ////////////////
///////////////////
//////////////// //////////////// //////////////// ////////////////
///////////////////

constexpr int x_infty = 1000'000'000 + 1;

vector<int> dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};

int main() {
  // 高速な入出力
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << setprecision(15); // 浮動小数の表示の精度

  int n, m;
  cin >> n >> m;
  vector<int> x_s = {-x_infty, -1, 0, 1, x_infty},
              y_s = {-x_infty, -1, 0, 1, x_infty};
  vector<int> vert_x1(n), vert_x2(n), vert_y(n);
  rep(i, n) {
    cin >> vert_x1[i] >> vert_x2[i] >> vert_y[i];
    x_s.push_back(vert_x1[i]);
    x_s.push_back(vert_x2[i]);
    y_s.push_back(vert_y[i]);
  }
  vector<int> hori_x(m), hori_y1(m), hori_y2(m);
  rep(k, m) {
    cin >> hori_x[k] >> hori_y1[k] >> hori_y2[k];
    x_s.push_back(hori_x[k]);
    y_s.push_back(hori_y1[k]);
    y_s.push_back(hori_y2[k]);
  }
  sort(x_s.begin(), x_s.end());
  sort(y_s.begin(), y_s.end());
  x_s.erase(unique(x_s.begin(), x_s.end()), x_s.end());
  y_s.erase(unique(y_s.begin(), y_s.end()), y_s.end());

  // (x_cmp,y_cmp) を左上に持つ長方形も (x_cmp,y_cmp) と書く
  // is_wall[x_cmp][y_cmp][i] = (x_cmp,y_cmp) to (x_cmp+dx[i],y_cmp+dy[i])
  // が壁か?
  vector<vector<vector<bool>>> is_wall(
      x_s.size() - 1,
      vector<vector<bool>>(y_s.size() - 1, vector<bool>(4, false)));
  rep(i, n) {
    int x1_cmp = lower_bound(x_s.begin(), x_s.end(), vert_x1[i]) - x_s.begin();
    int x2_cmp = lower_bound(x_s.begin(), x_s.end(), vert_x2[i]) - x_s.begin();
    int y_cmp = lower_bound(y_s.begin(), y_s.end(), vert_y[i]) - y_s.begin();
    for (int x_cmp = x1_cmp; x_cmp < x2_cmp; x_cmp++) {
      is_wall[x_cmp][y_cmp - 1][1] = is_wall[x_cmp][y_cmp][3] = true;
    }
  }
  rep(k, m) {
    int x_cmp = lower_bound(x_s.begin(), x_s.end(), hori_x[k]) - x_s.begin();
    int y1_cmp = lower_bound(y_s.begin(), y_s.end(), hori_y1[k]) - y_s.begin();
    int y2_cmp = lower_bound(y_s.begin(), y_s.end(), hori_y2[k]) - y_s.begin();
    for (int y_cmp = y1_cmp; y_cmp < y2_cmp; y_cmp++) {
      is_wall[x_cmp - 1][y_cmp][0] = is_wall[x_cmp][y_cmp][2] = true;
    }
  }

  bool is_infty = false;
  ll ans = 0;
  vector<vector<bool>> used(x_s.size() - 1,
                            vector<bool>(y_s.size() - 1, false));

  int x0 = lower_bound(x_s.begin(), x_s.end(), 0) - x_s.begin();
  int y0 = lower_bound(y_s.begin(), y_s.end(), 0) - y_s.begin();
  auto bfs = [&](int x_cmp_0, int y_cmp_0) {
    queue<int> x_cmps, y_cmps;
    used[x_cmp_0][y_cmp_0] = true;
    x_cmps.push(x_cmp_0);
    y_cmps.push(y_cmp_0);
    while (!x_cmps.empty()) {
      int x_cmp = x_cmps.front();
      x_cmps.pop();
      int y_cmp = y_cmps.front();
      y_cmps.pop();
      ans +=
          ((ll)x_s[x_cmp + 1] - x_s[x_cmp]) * ((ll)y_s[y_cmp + 1] - y_s[y_cmp]);
      rep(i, 4) {
        if (is_wall[x_cmp][y_cmp][i]) {
          continue;
        }
        int x_cmp_new = x_cmp + dx[i];
        int y_cmp_new = y_cmp + dy[i];
        if (used[x_cmp_new][y_cmp_new]) {
          continue;
        }
        used[x_cmp_new][y_cmp_new] = true;
        if (x_cmp_new == 0 || x_cmp_new + 2 == (int)x_s.size() ||
            y_cmp_new == 0 || y_cmp_new + 2 == (int)y_s.size()) {
          is_infty = true;
          return;
        }
        x_cmps.push(x_cmp_new);
        y_cmps.push(y_cmp_new);
      }
    }
  };
  bfs(x0, y0);
  if (is_infty) {
    cout << "INF\\n";
  } else {
    cout << ans << '\\n';
  }

  return 0;
}


Error: 0

Fixed submission:

// #define _GLIBCXX_DEBUG
// #define _LIBCPP_DEBUG 0

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>    // assert
#include <cmath>      // abs など
#include <functional> // greater など
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric> // accumulate, gcd など
#include <queue>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
typedef long long ll;

//////////////// //////////////// //////////////// ////////////////
///////////////////
//////////////// //////////////// //////////////// ////////////////
///////////////////

constexpr int x_infty = 1000'000'000 + 1;

vector<int> dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};

int main() {
  // 高速な入出力
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << setprecision(15); // 浮動小数の表示の精度

  int n, m;
  cin >> n >> m;
  vector<int> x_s = {-x_infty, 0, x_infty}, y_s = {-x_infty, 0, x_infty};
  vector<int> vert_x1(n), vert_x2(n), vert_y(n);
  rep(i, n) {
    cin >> vert_x1[i] >> vert_x2[i] >> vert_y[i];
    x_s.push_back(vert_x1[i]);
    x_s.push_back(vert_x2[i]);
    y_s.push_back(vert_y[i]);
  }
  vector<int> hori_x(m), hori_y1(m), hori_y2(m);
  rep(k, m) {
    cin >> hori_x[k] >> hori_y1[k] >> hori_y2[k];
    x_s.push_back(hori_x[k]);
    y_s.push_back(hori_y1[k]);
    y_s.push_back(hori_y2[k]);
  }
  sort(x_s.begin(), x_s.end());
  sort(y_s.begin(), y_s.end());
  x_s.erase(unique(x_s.begin(), x_s.end()), x_s.end());
  y_s.erase(unique(y_s.begin(), y_s.end()), y_s.end());

  // (x_cmp,y_cmp) を左上に持つ長方形も (x_cmp,y_cmp) と書く
  // is_wall[x_cmp][y_cmp][i] = (x_cmp,y_cmp) to (x_cmp+dx[i],y_cmp+dy[i])
  // が壁か?
  vector<vector<vector<bool>>> is_wall(
      x_s.size() - 1,
      vector<vector<bool>>(y_s.size() - 1, vector<bool>(4, false)));
  rep(i, n) {
    int x1_cmp = lower_bound(x_s.begin(), x_s.end(), vert_x1[i]) - x_s.begin();
    int x2_cmp = lower_bound(x_s.begin(), x_s.end(), vert_x2[i]) - x_s.begin();
    int y_cmp = lower_bound(y_s.begin(), y_s.end(), vert_y[i]) - y_s.begin();
    for (int x_cmp = x1_cmp; x_cmp < x2_cmp; x_cmp++) {
      is_wall[x_cmp][y_cmp - 1][1] = is_wall[x_cmp][y_cmp][3] = true;
    }
  }
  rep(k, m) {
    int x_cmp = lower_bound(x_s.begin(), x_s.end(), hori_x[k]) - x_s.begin();
    int y1_cmp = lower_bound(y_s.begin(), y_s.end(), hori_y1[k]) - y_s.begin();
    int y2_cmp = lower_bound(y_s.begin(), y_s.end(), hori_y2[k]) - y_s.begin();
    for (int y_cmp = y1_cmp; y_cmp < y2_cmp; y_cmp++) {
      is_wall[x_cmp - 1][y_cmp][0] = is_wall[x_cmp][y_cmp][2] = true;
    }
  }

  bool is_infty = false;
  ll ans = 0;
  vector<vector<bool>> used(x_s.size() - 1,
                            vector<bool>(y_s.size() - 1, false));

  int x0 = lower_bound(x_s.begin(), x_s.end(), 0) - x_s.begin();
  int y0 = lower_bound(y_s.begin(), y_s.end(), 0) - y_s.begin();
  auto bfs = [&](int x_cmp_0, int y_cmp_0) {
    queue<int> x_cmps, y_cmps;
    used[x_cmp_0][y_cmp_0] = true;
    x_cmps.push(x_cmp_0);
    y_cmps.push(y_cmp_0);
    while (!x_cmps.empty()) {
      int x_cmp = x_cmps.front();
      x_cmps.pop();
      int y_cmp = y_cmps.front();
      y_cmps.pop();
      ans +=
          ((ll)x_s[x_cmp + 1] - x_s[x_cmp]) * ((ll)y_s[y_cmp + 1] - y_s[y_cmp]);
      rep(i, 4) {
        if (is_wall[x_cmp][y_cmp][i]) {
          continue;
        }
        int x_cmp_new = x_cmp + dx[i];
        int y_cmp_new = y_cmp + dy[i];
        if (used[x_cmp_new][y_cmp_new]) {
          continue;
        }
        used[x_cmp_new][y_cmp_new] = true;
        if (x_cmp_new == 0 || x_cmp_new + 2 == (int)x_s.size() ||
            y_cmp_new == 0 || y_cmp_new + 2 == (int)y_s.size()) {
          is_infty = true;
          continue;
        }
        x_cmps.push(x_cmp_new);
        y_cmps.push(y_cmp_new);
      }
    }
  };
  bfs(x0, y0);
  if (is_infty) {
    cout << "INF\\n";
  } else {
    cout << ans << '\\n';
  }

  return 0;
}