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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>

struct line_t {
  std::pair<int, int> range;
  int pos;
  bool xaxis;

  line_t() {}
  line_t(std::pair<int, int> range, int pos, bool xaxis)
      : range(range), pos(pos), xaxis(xaxis) {}
};

int main() {
  size_t n, m;
  std::cin >> n >> m;

  std::vector<int> xs, ys;
  std::vector<line_t> lines;

  if (n == 1 || m == 1) {
    std::cout << "INF\\n";
    return 0;
  }

  for (size_t i = 0; i < n; i++) {
    int a, b, c;
    std::cin >> a >> b >> c;
    xs.push_back(a);
    xs.push_back(b);
    ys.push_back(c);
    lines.emplace_back(std::make_pair(a, b), c, true);
  }

  for (size_t i = 0; i < m; i++) {
    int d, e, f;
    std::cin >> d >> e >> f;
    xs.push_back(d);
    ys.push_back(e);
    ys.push_back(f);
    lines.emplace_back(std::make_pair(e, f), d, false);
  }

  xs.push_back(2e+9);
  xs.push_back(0);
  xs.push_back(-2e+9);
  ys.push_back(2e+9);
  ys.push_back(0);
  ys.push_back(-2e+9);

  std::sort(xs.begin(), xs.end());
  std::sort(ys.begin(), ys.end());
  //[]: i -> x
  // lowerbound: x -> i
  xs.erase(std::unique(xs.begin(), xs.end()), xs.end());
  ys.erase(std::unique(ys.begin(), ys.end()), ys.end());

  std::vector<std::vector<int>> hng(xs.size(), std::vector<int>(ys.size()));
  auto wng = hng;

  for (auto &&line : lines) {
    if (line.xaxis) {
      int ix1 =
          std::lower_bound(xs.begin(), xs.end(), line.range.first) - xs.begin();
      int ix2 = std::lower_bound(xs.begin(), xs.end(), line.range.second) -
                xs.begin();
      int iy = std::lower_bound(ys.begin(), ys.end(), line.pos) - ys.begin();
      hng[ix1][iy]++;
      hng[ix2][iy]--;
    }
    if (!line.xaxis) {
      int iy1 =
          std::lower_bound(ys.begin(), ys.end(), line.range.first) - ys.begin();
      int iy2 = std::lower_bound(ys.begin(), ys.end(), line.range.second) -
                ys.begin();
      int ix = std::lower_bound(xs.begin(), xs.end(), line.pos) - xs.begin();
      wng[ix][iy1]++;
      wng[ix][iy2]--;
    }
  }

  for (size_t i = 0; i < xs.size(); i++) {
    for (size_t j = 0; j < ys.size(); j++) {
      if (i < (xs.size() - 1))
        hng[i + 1][j] += hng[i][j];
      if (j < (ys.size() - 1))
        wng[i][j + 1] += wng[i][j];
    }
  }

  std::queue<std::pair<int, int>> search;
  std::pair<int, int> zero = {
      std::lower_bound(xs.begin(), xs.end(), 0) - xs.begin(),
      std::lower_bound(ys.begin(), ys.end(), 0) - ys.begin()};
  search.push(zero);

  std::vector<std::vector<int>> flag(xs.size() - 1,
                                     std::vector<int>(ys.size() - 1, 0));
  flag[zero.first][zero.second] = 1;

  long long area = 0;
  while (!search.empty()) {
    auto searching = search.front();
    if (searching.first < 1 || searching.second < 1 ||
        searching.first >= (xs.size() - 2) ||
        searching.second >= (ys.size() - 2)) {
      std::cout << "INF\\n";
      return 0;
    }
    area += 1LL * (xs[searching.first + 1] - xs[searching.first]) *
            (ys[searching.second + 1] - ys[searching.second]);
    search.pop();
    if (!wng[searching.first][searching.second] &&
        !flag[searching.first - 1][searching.second]) {
      search.push({searching.first - 1, searching.second});
      flag[searching.first - 1][searching.second] = true;
    }
    if (!hng[searching.first][searching.second] &&
        !flag[searching.first][searching.second - 1]) {
      search.push({searching.first, searching.second - 1});
      flag[searching.first][searching.second - 1] = true;
    }
    if (searching.first < (xs.size() - 2) &&
        !wng[searching.first + 1][searching.second] &&
        !flag[searching.first + 1][searching.second]) {
      search.push({searching.first + 1, searching.second});
      flag[searching.first + 1][searching.second] = true;
    }
    if (searching.second < (ys.size() - 2) &&
        !hng[searching.first][searching.second + 1] &&
        !flag[searching.first][searching.second + 1]) {
      search.push({searching.first, searching.second + 1});
      flag[searching.first][searching.second + 1] = true;
    }
  }
  std::cout << area << "\\n";
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>

struct block_t {
  std::pair<int, int> xbound, ybound;
  block_t() {}
  block_t(const std::pair<int, int> &x, const std::pair<int, int> &y)
      : xbound(x), ybound(y) {}

  bool is_through(const std::pair<int, int> &pos,
                  const std::pair<int, int> &dir) const {
    double tx = pos.first + 0.5 * (1 + dir.first);
    double ty = pos.second + 0.5 * (1 + dir.second);
    return !((double(xbound.first) <= tx) && (tx <= double(xbound.second)) &&
             (double(ybound.first) <= ty && ty <= double(ybound.second)));
  }
};

int main() {
  size_t n, m;
  std::cin >> n >> m;

  using pos_t = std::pair<int, int>;

  std::vector<block_t> blocks;

  bool xu = false, xl = false, yu = false, yl = false;

  for (size_t i = 0; i < n; i++) {
    int a, b, c;
    std::cin >> a >> b >> c;
    if (c > 0)
      yu = true;
    if (c < 0)
      yl = true;
    blocks.push_back(block_t({a, b}, {c, c}));
  }

  for (size_t i = 0; i < m; i++) {
    int d, e, f;
    std::cin >> d >> e >> f;
    if (d > 0)
      xu = true;
    if (d < 0)
      xl = true;
    blocks.push_back(block_t({d, d}, {e, f}));
  }

  std::vector<std::pair<int, int>> dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
  int area = 0;
  if (!(xu && xl && yu && yl)) {
    std::cout << "INF\\n";
  } else {
    std::queue<std::pair<int, int>> search;
    search.push({0, 0});
    std::map<std::pair<int, int>, bool> flag;
    flag[{0, 0}] = true;
    while (!search.empty()) {
      auto searching = search.front();
      area++;
      search.pop();
      for (auto &&dir : dirs) {
        std::pair<int, int> next = {searching.first + dir.first,
                                    searching.second + dir.second};
        if (!flag[next] && std::all_of(blocks.begin(), blocks.end(),
                                       [&searching, &dir](const block_t &b) {
                                         return b.is_through(searching, dir);
                                       })) {
          flag[next] = true;
          search.push(next);
        }
      }
    }
    std::cout << area << "\\n";
  }

  return 0;
}