Problem p02680 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
template <typename T> void fin(T const &t) {
  std::cout << t << std::endl;
  exit(0);
}

struct line {
  int64_t p, q, r;
  line() {}
};
void su(std::vector<int> &v) {
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(), v.end()), v.end());
}

int main() {
  int N, M;
  std::cin >> N >> M;
  std::vector<int> xs(M), ys(N);
  std::vector<line> hL(N), vL(M);
  // (p...q, r) / (p, q...r)
  for (int i = 0; i < N; ++i) {
    std::cin >> hL[i].p >> hL[i].q >> hL[i].r;
    ys[i] = hL[i].r;
  }
  for (int i = 0; i < M; ++i) {
    std::cin >> vL[i].p >> vL[i].q >> vL[i].r;
    xs[i] = vL[i].p;
  }
  su(xs);
  su(ys);
  if (xs[0] >= 0 || xs.back() <= 0 || ys[0] >= 0 || ys.back() <= 0)
    fin("INF");

  // walls
  int XS = xs.size(), YS = ys.size();
  std::vector<std::vector<int>> hW(YS, std::vector<int>(XS, 0)),
      vW(YS, std::vector<int>(YS, 0));
  for (auto const &w : hL) { // w.p < w.q : given
    int x1 = std::max(
        0, (int)(std::lower_bound(xs.begin(), xs.end(), w.p) - xs.begin()));
    int x2 = std::min(XS, (int)(std::upper_bound(xs.begin(), xs.end(), w.q) -
                                xs.begin())) -
             1;
    if (x2 <= 0 || x1 >= XS - 1)
      continue;
    int y = std::lower_bound(ys.begin(), ys.end(), w.r) - ys.begin();
    assert(0 <= y && y <= YS - 1);
    assert(0 <= x1 && x1 <= XS - 2);
    assert(1 <= x2 && x2 <= XS - 1);
    ++hW[y][x1];
    --hW[y][x2];
  }
  for (auto const &w : vL) { // w.q < w.r : given
    int x = std::lower_bound(xs.begin(), xs.end(), w.p) - xs.begin();
    int y1 = std::max(
        0, (int)(std::lower_bound(ys.begin(), ys.end(), w.q) - ys.begin()));
    int y2 = std::min(YS, (int)(std::upper_bound(ys.begin(), ys.end(), w.r) -
                                ys.begin())) -
             1;
    if (y2 <= 0 || y1 >= YS - 1)
      continue;
    assert(0 <= x && x <= XS - 1);
    assert(0 <= y1 && y1 <= YS - 2);
    assert(1 <= y2 && y2 <= YS - 1);
    ++vW[y1][x];
    --vW[y2][x];
  }
  for (int y = 0; y < YS; ++y)
    for (int x = 1; x < XS; ++x)
      hW[y][x] += hW[y][x - 1];
  for (int x = 0; x < XS; ++x)
    for (int y = 1; y < YS; ++y)
      vW[y][x] += vW[y - 1][x];
  // bfs
  std::vector<std::vector<bool>> visited(YS - 1,
                                         std::vector<bool>(XS - 1, false));
  std::queue<std::pair<int, int>> q;
  int x = std::lower_bound(xs.begin(), xs.end(), 0) - xs.begin() - 1;
  int y = std::lower_bound(ys.begin(), ys.end(), 0) - ys.begin() - 1;
  q.push(std::make_pair(x, y));
  while (!q.empty()) {
    auto const &p = q.front();
    x = p.first;
    y = p.second;
    q.pop();
    if (visited[y][x])
      continue;
    visited[y][x] = true;
    // ydec
    if (hW[y][x] < 1) {
      if (y <= 0)
        fin("INF");
      if (!visited[y - 1][x])
        q.push(std::make_pair(x, y - 1));
    }
    // yinc
    if (hW[y + 1][x] < 1) {
      if (y >= YS - 2)
        fin("INF");
      if (!visited[y + 1][x])
        q.push(std::make_pair(x, y + 1));
    }
    // xdec
    if (vW[y][x] < 1) {
      if (x <= 0)
        fin("INF");
      if (!visited[y][x - 1])
        q.push(std::make_pair(x - 1, y));
    }
    // xinc
    if (vW[y][x + 1] < 1) {
      if (x >= XS - 2)
        fin("INF");
      if (!visited[y][x + 1])
        q.push(std::make_pair(x + 1, y));
    }
  }
  // calc area
  int64_t ans = 0;
  for (int y = 0; y < YS - 1; ++y)
    for (int x = 0; x < XS - 1; ++x)
      if (visited[y][x]) {
        ans += (int64_t)(xs[x + 1] - xs[x]) * (ys[y + 1] - ys[y]);
      }
  fin(ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
template <typename T> void fin(T const &t) {
  std::cout << t << std::endl;
  exit(0);
}

struct line {
  int64_t p, q, r;
  line() {}
};
void su(std::vector<int> &v) {
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(), v.end()), v.end());
}

int main() {
  int N, M;
  std::cin >> N >> M;
  std::vector<int> xs(M), ys(N);
  std::vector<line> hL(N), vL(M);
  // (p...q, r) / (p, q...r)
  for (int i = 0; i < N; ++i) {
    std::cin >> hL[i].p >> hL[i].q >> hL[i].r;
    ys[i] = hL[i].r;
  }
  for (int i = 0; i < M; ++i) {
    std::cin >> vL[i].p >> vL[i].q >> vL[i].r;
    xs[i] = vL[i].p;
  }
  su(xs);
  su(ys);
  if (xs[0] >= 0 || xs.back() <= 0 || ys[0] >= 0 || ys.back() <= 0)
    fin("INF");

  // walls
  int XS = xs.size(), YS = ys.size();
  std::vector<std::vector<int>> hW(YS, std::vector<int>(XS, 0)),
      vW(YS, std::vector<int>(XS, 0));
  for (auto const &w : hL) { // w.p < w.q : given
    int x1 = std::max(
        0, (int)(std::lower_bound(xs.begin(), xs.end(), w.p) - xs.begin()));
    int x2 = std::min(XS, (int)(std::upper_bound(xs.begin(), xs.end(), w.q) -
                                xs.begin())) -
             1;
    if (x2 <= 0 || x1 >= XS - 1)
      continue;
    int y = std::lower_bound(ys.begin(), ys.end(), w.r) - ys.begin();
    assert(0 <= y && y <= YS - 1);
    assert(0 <= x1 && x1 <= XS - 2);
    assert(1 <= x2 && x2 <= XS - 1);
    ++hW[y][x1];
    --hW[y][x2];
  }
  for (auto const &w : vL) { // w.q < w.r : given
    int x = std::lower_bound(xs.begin(), xs.end(), w.p) - xs.begin();
    int y1 = std::max(
        0, (int)(std::lower_bound(ys.begin(), ys.end(), w.q) - ys.begin()));
    int y2 = std::min(YS, (int)(std::upper_bound(ys.begin(), ys.end(), w.r) -
                                ys.begin())) -
             1;
    if (y2 <= 0 || y1 >= YS - 1)
      continue;
    assert(0 <= x && x <= XS - 1);
    assert(0 <= y1 && y1 <= YS - 2);
    assert(1 <= y2 && y2 <= YS - 1);
    ++vW[y1][x];
    --vW[y2][x];
  }
  for (int y = 0; y < YS; ++y)
    for (int x = 1; x < XS; ++x)
      hW[y][x] += hW[y][x - 1];
  for (int x = 0; x < XS; ++x)
    for (int y = 1; y < YS; ++y)
      vW[y][x] += vW[y - 1][x];
  // bfs
  std::vector<std::vector<bool>> visited(YS - 1,
                                         std::vector<bool>(XS - 1, false));
  std::queue<std::pair<int, int>> q;
  int x = std::lower_bound(xs.begin(), xs.end(), 0) - xs.begin() - 1;
  int y = std::lower_bound(ys.begin(), ys.end(), 0) - ys.begin() - 1;
  q.push(std::make_pair(x, y));
  while (!q.empty()) {
    auto const &p = q.front();
    x = p.first;
    y = p.second;
    q.pop();
    if (visited[y][x])
      continue;
    visited[y][x] = true;
    // ydec
    if (hW[y][x] < 1) {
      if (y <= 0)
        fin("INF");
      if (!visited[y - 1][x])
        q.push(std::make_pair(x, y - 1));
    }
    // yinc
    if (hW[y + 1][x] < 1) {
      if (y >= YS - 2)
        fin("INF");
      if (!visited[y + 1][x])
        q.push(std::make_pair(x, y + 1));
    }
    // xdec
    if (vW[y][x] < 1) {
      if (x <= 0)
        fin("INF");
      if (!visited[y][x - 1])
        q.push(std::make_pair(x - 1, y));
    }
    // xinc
    if (vW[y][x + 1] < 1) {
      if (x >= XS - 2)
        fin("INF");
      if (!visited[y][x + 1])
        q.push(std::make_pair(x + 1, y));
    }
  }
  // calc area
  int64_t ans = 0;
  for (int y = 0; y < YS - 1; ++y)
    for (int x = 0; x < XS - 1; ++x)
      if (visited[y][x]) {
        ans += (int64_t)(xs[x + 1] - xs[x]) * (ys[y + 1] - ys[y]);
      }
  fin(ans);
  return 0;
}