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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vi2;
typedef vector<vi2> vi3;
typedef pair<int, int> pii;
typedef vector<pii> vii;
typedef vector<ll> vll;
typedef vector<vll> vll2;
typedef vector<vll2> vll3;
typedef vector<bool> vb;
typedef vector<vb> vb2;

#define el '\\n'
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repi(i, a, b) for (int i = a; i >= b; i--)
#define umap unordered_map
#define uset unordered_set
#define vec vector
#define loop(a) for (auto &x : a)
#define all(a) a.begin(), a.end()
#define mp make_pair

struct Segment {
  int a, b, c;
  Segment(int a, int b, int c) : a(a), b(b), c(c) {}

  bool operator<(const Segment that) const {
    return c < that.c || (c == that.c && mp(a, b) < mp(that.a, that.b));
  }
};

const ll INF = 1e9 + 123;

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int n, m;
  cin >> n >> m;
  vec<Segment> ns;
  set<int> xs, ys; // 行，列
  rep(i, 0, n) {
    int a, b, c;
    cin >> a >> b >> c;
    ns.emplace_back(a, b, c);
    xs.insert(a);
    xs.insert(b);
    ys.insert(c);
  }
  xs.insert(-INF);
  xs.insert(INF);
  ns.emplace_back(-INF, INF, -INF);
  ns.emplace_back(-INF, INF, INF);
  n += 2;
  vec<Segment> ew;
  rep(i, 0, m) {
    int d, e, f;
    cin >> d >> e >> f;
    ew.emplace_back(e, f, d);
    ys.insert(e);
    ys.insert(f);
    xs.insert(d);
  }
  ys.insert(-INF);
  ys.insert(INF);
  ew.emplace_back(-INF, INF, -INF);
  ew.emplace_back(-INF, INF, INF);
  m += 2;

  sort(all(ns));
  sort(all(ew));

  // 先看行
  vi xss(xs.begin(), xs.end());
  vi yss(ys.begin(), ys.end());
  int szx = xss.size(), szy = yss.size();
  int total = (szx - 1) * szy;
#ifdef LOCAL
  cout << "total:" << total << el;
#endif
  vll area(total);
  vec<set<int>> no_adj(total);

  int cow = -1;

#ifdef LOCAL
  cout << "finish reading" << el;
  cout << "xss.sz=" << szx << el;
  // cout << "xss: ";
  // loop(xss) {
  //     cout << x << ' ';
  // }
  // cout << el;
  cout << "yss.sz=" << szy << el;
#endif

  // 查看行与行之间的分割
  rep(i, 0, xss.size() - 2) {
    int x1 = xss[i], x2 = xss[i + 1];
    vii delta;
    rep(k, 0, m) {
      if (ew[k].c == x2) {
        delta.emplace_back(ew[k].a, 1);
        delta.emplace_back(ew[k].b, -1);
      }
    }
    sort(all(delta));
    int covering = 0;
    int k = 0;
    rep(j, 0, yss.size() - 1) {
      int y1 = yss[j], y2 = yss[j + 1];
      int number = i * szy + j;
      if (abs(x1) == INF || abs(x2) == INF || abs(y1) == INF ||
          abs(y2) == INF) {
        area[number] = -1;
      } else {
        area[number] = (ll)(y2 - y1) * (x2 - x1);
      }
#ifdef LOCAL
      // cout << "[" << x1 << ',' << y1 << ',' << x2 << ',' << y2 << "]" << el;
#endif
      // 考虑矩形[x1,y1,x2,y2]下边有没有线段
      while (k < delta.size() && delta[k].first <= y1) {
        covering += delta[k].second;
        k++;
      }
#ifdef LOCAL
      assert(number < total);
#endif
      if (covering > 0) {
        int below = (i + 1) * szy + j;
#ifdef LOCAL
        assert(below < total);
        // cout << i << "," << j << "--" << i + 1 << "," << j << el;
#endif
        no_adj[number].insert(below);
        no_adj[below].insert(number);
      }

      if (x1 <= 0 && 0 <= x2 && y1 <= 0 && 0 <= y2) {
#ifdef LOCAL
        cout << "cow: " << i << ',' << j << el;
#endif
        cow = number;
      }
    }
  }

#ifdef LOCAL
  cout << "cow: " << cow << el;
  cout << "finish row checking" << el;
#endif

  // 查看列与列之间的分割
  rep(j, 0, yss.size() - 2) {
    int y1 = yss[j], y2 = yss[j + 1];
    vii delta;
    rep(k, 0, n) {
      if (ns[k].c == y2) {
        delta.emplace_back(ns[k].a, 1);
        delta.emplace_back(ns[k].b, -1);
      }
    }
    sort(all(delta));
    int covering = 0;
    int k = 0;
    rep(i, 0, xss.size() - 1) {
      int x1 = xss[i], x2 = xss[i + 1];
      // 考虑矩形[x1,y1,x2,y2]下边有没有线段
      while (k < delta.size() && delta[k].first <= x1) {
        covering += delta[k].second;
        k++;
      }
      int number = i * szy + j;
      if (covering > 0) {
        int right = i * szy + j + 1;
#ifdef LOCAL
        // cout << i << "," << j << "--" << i << "," << j + 1 << el;

#endif
        no_adj[number].insert(right);
        no_adj[right].insert(number);
      }
      if (x1 <= 0 && 0 <= x2 && y1 <= 0 && 0 <= y2) {
#ifdef LOCAL
        cout << "cow: " << i << ',' << j << el;
#endif
        cow = number;
      }
    }
  }

  if (cow == -1) {
    cout << "INF" << el;
  }

#ifdef LOCAL
  cout << "finish column checking" << el;
#endif

  queue<int> q;
  q.push(cow);
  ll ans = 0;
  vb visited(total);
  visited[cow] = true;
  while (!q.empty()) {
    int h = q.front();
    q.pop();
    if (area[h] == -1) {
#ifdef LOCAL
      cout << "boarder: " << h / szy << ',' << h % szy << el;
#endif
      ans = -1;
      break;
    }
    ans += area[h];
    const vi DIR{szy, 1, -szy, -1};
    loop(DIR) {
      int next = h + x;
      if (0 <= next && next < total && !visited[next] &&
          no_adj[h].count(next) == 0) {
        visited[next] = true;
        q.push(next);
      }
    }
  }
  if (ans == -1) {
    cout << "INF" << el;
  } else {
    cout << ans << el;
  }
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vi2;
typedef vector<vi2> vi3;
typedef pair<int, int> pii;
typedef vector<pii> vii;
typedef vector<ll> vll;
typedef vector<vll> vll2;
typedef vector<vll2> vll3;
typedef vector<bool> vb;
typedef vector<vb> vb2;

#define el '\\n'
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repi(i, a, b) for (int i = a; i >= b; i--)
#define umap unordered_map
#define uset unordered_set
#define vec vector
#define loop(a) for (auto &x : a)
#define all(a) a.begin(), a.end()
#define mp make_pair

struct Segment {
  int a, b, c;
  Segment(int a, int b, int c) : a(a), b(b), c(c) {}

  bool operator<(const Segment that) const {
    return c < that.c || (c == that.c && mp(a, b) < mp(that.a, that.b));
  }
};

const ll INF = 1e9 + 123;

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int n, m;
  cin >> n >> m;
  vec<Segment> ns;
  set<int> xs, ys; // 行，列
  rep(i, 0, n) {
    int a, b, c;
    cin >> a >> b >> c;
    ns.emplace_back(a, b, c);
    xs.insert(a);
    xs.insert(b);
    ys.insert(c);
  }
  xs.insert(-INF);
  xs.insert(INF);
  ns.emplace_back(-INF, INF, -INF);
  ns.emplace_back(-INF, INF, INF);
  n += 2;
  vec<Segment> ew;
  rep(i, 0, m) {
    int d, e, f;
    cin >> d >> e >> f;
    ew.emplace_back(e, f, d);
    ys.insert(e);
    ys.insert(f);
    xs.insert(d);
  }
  ys.insert(-INF);
  ys.insert(INF);
  ew.emplace_back(-INF, INF, -INF);
  ew.emplace_back(-INF, INF, INF);
  m += 2;

  sort(all(ns));
  sort(all(ew));

  // 先看行
  vi xss(xs.begin(), xs.end());
  vi yss(ys.begin(), ys.end());
  int szx = xss.size(), szy = yss.size();
  int total = (szx - 1) * szy;
#ifdef LOCAL
  cout << "total:" << total << el;
#endif
  vll area(total);
  vec<set<int>> no_adj(total);

  int cow = -1;

#ifdef LOCAL
  cout << "finish reading" << el;
  cout << "xss.sz=" << szx << el;
  // cout << "xss: ";
  // loop(xss) {
  //     cout << x << ' ';
  // }
  // cout << el;
  cout << "yss.sz=" << szy << el;
#endif

  // 查看行与行之间的分割
  rep(i, 0, xss.size() - 2) {
    int x1 = xss[i], x2 = xss[i + 1];
    vii delta;
    rep(k, 0, m) {
      if (ew[k].c == x2) {
        delta.emplace_back(ew[k].a, 1);
        delta.emplace_back(ew[k].b, -1);
      }
    }
    sort(all(delta));
    int covering = 0;
    int k = 0;
    rep(j, 0, yss.size() - 1) {
      int y1 = yss[j], y2 = yss[j + 1];
      int number = i * szy + j;
      if (abs(x1) == INF || abs(x2) == INF || abs(y1) == INF ||
          abs(y2) == INF) {
        area[number] = -1;
      } else {
        area[number] = (ll)(y2 - y1) * (x2 - x1);
      }
#ifdef LOCAL
      // cout << "[" << x1 << ',' << y1 << ',' << x2 << ',' << y2 << "]" << el;
#endif
      // 考虑矩形[x1,y1,x2,y2]下边有没有线段
      while (k < delta.size() && delta[k].first <= y1) {
        covering += delta[k].second;
        k++;
      }
#ifdef LOCAL
      assert(number < total);
#endif
      if (covering > 0) {
        int below = (i + 1) * szy + j;
#ifdef LOCAL
        assert(below < total);
        // cout << i << "," << j << "--" << i + 1 << "," << j << el;
#endif
        no_adj[number].insert(below);
        no_adj[below].insert(number);
      }

      if (x1 <= 0 && 0 <= x2 && y1 <= 0 && 0 <= y2) {
#ifdef LOCAL
        cout << "cow: " << i << ',' << j << el;
#endif
        cow = number;
      }
    }
  }

#ifdef LOCAL
  cout << "finish row checking" << el;
#endif

  // 查看列与列之间的分割
  rep(j, 0, yss.size() - 2) {
    int y1 = yss[j], y2 = yss[j + 1];
    vii delta;
    rep(k, 0, n) {
      if (ns[k].c == y2) {
        delta.emplace_back(ns[k].a, 1);
        delta.emplace_back(ns[k].b, -1);
      }
    }
    sort(all(delta));
    int covering = 0;
    int k = 0;
    rep(i, 0, xss.size() - 1) {
      int x1 = xss[i], x2 = xss[i + 1];
      // 考虑矩形[x1,y1,x2,y2]下边有没有线段
      while (k < delta.size() && delta[k].first <= x1) {
        covering += delta[k].second;
        k++;
      }
      if (covering > 0) {
        int number = i * szy + j;
        int right = i * szy + j + 1;
#ifdef LOCAL
        // cout << i << "," << j << "--" << i << "," << j + 1 << el;

#endif
        no_adj[number].insert(right);
        no_adj[right].insert(number);
      }
    }
  }

#ifdef LOCAL
  cout << "finish column checking" << el;
#endif

  queue<int> q;
  q.push(cow);
  ll ans = 0;
  vb visited(total);
  visited[cow] = true;
  while (!q.empty()) {
    int h = q.front();
    q.pop();
    if (area[h] == -1) {
#ifdef LOCAL
      cout << "boarder: " << h / szy << ',' << h % szy << el;
#endif
      ans = -1;
      break;
    }
    ans += area[h];
    const vi DIR{szy, 1, -szy, -1};
    loop(DIR) {
      int next = h + x;
      if (0 <= next && next < total && !visited[next] &&
          no_adj[h].count(next) == 0) {
        visited[next] = true;
        q.push(next);
      }
    }
  }
  if (ans == -1) {
    cout << "INF" << el;
  } else {
    cout << ans << el;
  }
}