Problem p02680 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

const int N = 5000;

struct NS {
  int a, b, c;
} ns[N + 5];
struct EW {
  int d, e, f;
} ew[N + 5];

int t_ns[N + 5], t_ew[N + 5], r_ns[N + 5], r_ew[N + 5];

template <int N> struct Disjoint_Set_Union {
  int p[N + 5], sz[N + 5];
  void init(int n) {
    for (int i = 0; i <= n; ++i) {
      p[i] = i;
      sz[i] = 1;
    }
  }
  int find(int x) { return p[x] == x ? p[x] : p[x] = find(p[x]); }
  bool funion(int x, int y) {
    int fx = find(x), fy = find(y);
    if (fx == fy)
      return false;
    if (sz[fx] < sz[fy])
      swap(fx, fy);
    p[fy] = fx;
    sz[fx] += sz[fy];
    return true;
  }
};
Disjoint_Set_Union<N> dsu;

bool no_ns[N + 5][N + 5], no_ew[N + 5][N + 5];

int main() {
  int n, m, a, b, c, d, e, f;
  scanf("%d %d", &n, &m);
  int cnt_ns = 0, cnt_ew = 0;
  t_ns[++cnt_ns] = 0;
  t_ew[++cnt_ew] = 0;
  for (int i = 1; i <= n; ++i) {
    scanf("%d %d %d", &a, &b, &c);
    t_ns[++cnt_ns] = a;
    t_ns[++cnt_ns] = b;
    t_ew[++cnt_ew] = c;
    ns[i] = {a, b, c};
  }
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %d", &d, &e, &f);
    t_ns[++cnt_ns] = d;
    t_ew[++cnt_ew] = e;
    t_ew[++cnt_ew] = f;
    ew[i] = {d, e, f};
  }
  sort(t_ns + 1, t_ns + cnt_ns + 1);
  auto ed_ns = unique(t_ns + 1, t_ns + cnt_ns + 1);
  sort(t_ew + 1, t_ew + cnt_ew + 1);
  auto ed_ew = unique(t_ew + 1, t_ew + cnt_ew + 1);
  for (int i = 1; i <= n; ++i) {
    int tmp = lower_bound(t_ns + 1, ed_ns, ns[i].a) - t_ns;
    r_ns[tmp] = ns[i].a;
    ns[i].a = tmp;
    tmp = lower_bound(t_ns + 1, ed_ns, ns[i].b) - t_ns;
    r_ns[tmp] = ns[i].b;
    ns[i].b = tmp;
    tmp = lower_bound(t_ew + 1, ed_ew, ns[i].c) - t_ew;
    r_ew[tmp] = ns[i].c;
    ns[i].c = tmp;
    for (int j = ns[i].a + 1; j <= ns[i].b; ++j) {
      no_ns[j][ns[i].c] = true;
    }
  }
  for (int i = 1; i <= m; ++i) {
    int tmp = lower_bound(t_ns + 1, ed_ns, ew[i].d) - t_ns;
    r_ns[tmp] = ew[i].d;
    ew[i].d = tmp;
    tmp = lower_bound(t_ew + 1, ed_ew, ew[i].e) - t_ew;
    r_ew[tmp] = ew[i].e;
    ew[i].e = tmp;
    tmp = lower_bound(t_ew + 1, ed_ew, ew[i].f) - t_ew;
    r_ew[tmp] = ew[i].f;
    ew[i].f = tmp;
    for (int j = ew[i].e + 1; j <= ew[i].f; ++j) {
      no_ew[ew[i].d][j] = true;
    }
  }
  int ns_0 = lower_bound(t_ns + 1, ed_ns, 0) - t_ns;
  int ew_0 = lower_bound(t_ew + 1, ed_ew, 0) - t_ew;
  int ns_max = ed_ns - t_ns;
  int ew_max = ed_ew - t_ew;
  dsu.init(ns_max * ew_max);
  for (int i = 1; i < ns_max; ++i) {
    for (int j = 1; j < ew_max; ++j) {
      int id = (i - 1) * ew_max + j;
      if (!no_ns[i][j])
        dsu.funion(id, id + 1);
      if (!no_ew[i][j])
        dsu.funion(id, id + ew_max);
    }
  }
  int parent = dsu.find((ns_0 - 1) * ew_max + ew_0);
  long long ans = 0;
  for (int i = 1; i <= ns_max; ++i) {
    for (int j = 1, l = 0; j <= ew_max; ++j) {
      int id = (i - 1) * ew_max + j;
      if (dsu.find(id) == parent) {
        if (i == 1 || i == ns_max || j == 1 || j == ew_max) {
          ans = LLONG_MAX;
          goto end;
        }
        if (dsu.find(id + 1) != parent) {
          ans += (long long)(r_ns[i] - r_ns[i - 1]) *
                 (long long)(r_ew[j] - r_ew[l]);
        }
      } else
        l = j;
    }
  }
end:
  if (ans != LLONG_MAX)
    printf("%lld\n", ans);
  else
    printf("INF\n");
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int N = 5000;

struct NS {
  int a, b, c;
} ns[N + 5];
struct EW {
  int d, e, f;
} ew[N + 5];

int t_ns[N + 5], t_ew[N + 5], r_ns[N + 5], r_ew[N + 5];

template <int N> struct Disjoint_Set_Union {
  int p[N + 5], sz[N + 5];
  void init(int n) {
    for (int i = 0; i <= n; ++i) {
      p[i] = i;
      sz[i] = 1;
    }
  }
  int find(int x) { return p[x] == x ? p[x] : p[x] = find(p[x]); }
  bool funion(int x, int y) {
    int fx = find(x), fy = find(y);
    if (fx == fy)
      return false;
    if (sz[fx] < sz[fy])
      swap(fx, fy);
    p[fy] = fx;
    sz[fx] += sz[fy];
    return true;
  }
};
Disjoint_Set_Union<N * N> dsu;

bool no_ns[N + 5][N + 5], no_ew[N + 5][N + 5];

int main() {
  int n, m, a, b, c, d, e, f;
  scanf("%d %d", &n, &m);
  int cnt_ns = 0, cnt_ew = 0;
  t_ns[++cnt_ns] = 0;
  t_ew[++cnt_ew] = 0;
  for (int i = 1; i <= n; ++i) {
    scanf("%d %d %d", &a, &b, &c);
    t_ns[++cnt_ns] = a;
    t_ns[++cnt_ns] = b;
    t_ew[++cnt_ew] = c;
    ns[i] = {a, b, c};
  }
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %d", &d, &e, &f);
    t_ns[++cnt_ns] = d;
    t_ew[++cnt_ew] = e;
    t_ew[++cnt_ew] = f;
    ew[i] = {d, e, f};
  }
  sort(t_ns + 1, t_ns + cnt_ns + 1);
  auto ed_ns = unique(t_ns + 1, t_ns + cnt_ns + 1);
  sort(t_ew + 1, t_ew + cnt_ew + 1);
  auto ed_ew = unique(t_ew + 1, t_ew + cnt_ew + 1);
  for (int i = 1; i <= n; ++i) {
    int tmp = lower_bound(t_ns + 1, ed_ns, ns[i].a) - t_ns;
    r_ns[tmp] = ns[i].a;
    ns[i].a = tmp;
    tmp = lower_bound(t_ns + 1, ed_ns, ns[i].b) - t_ns;
    r_ns[tmp] = ns[i].b;
    ns[i].b = tmp;
    tmp = lower_bound(t_ew + 1, ed_ew, ns[i].c) - t_ew;
    r_ew[tmp] = ns[i].c;
    ns[i].c = tmp;
    for (int j = ns[i].a + 1; j <= ns[i].b; ++j) {
      no_ns[j][ns[i].c] = true;
    }
  }
  for (int i = 1; i <= m; ++i) {
    int tmp = lower_bound(t_ns + 1, ed_ns, ew[i].d) - t_ns;
    r_ns[tmp] = ew[i].d;
    ew[i].d = tmp;
    tmp = lower_bound(t_ew + 1, ed_ew, ew[i].e) - t_ew;
    r_ew[tmp] = ew[i].e;
    ew[i].e = tmp;
    tmp = lower_bound(t_ew + 1, ed_ew, ew[i].f) - t_ew;
    r_ew[tmp] = ew[i].f;
    ew[i].f = tmp;
    for (int j = ew[i].e + 1; j <= ew[i].f; ++j) {
      no_ew[ew[i].d][j] = true;
    }
  }
  int ns_0 = lower_bound(t_ns + 1, ed_ns, 0) - t_ns;
  int ew_0 = lower_bound(t_ew + 1, ed_ew, 0) - t_ew;
  int ns_max = ed_ns - t_ns;
  int ew_max = ed_ew - t_ew;
  dsu.init(ns_max * ew_max);
  for (int i = 1; i < ns_max; ++i) {
    for (int j = 1; j < ew_max; ++j) {
      int id = (i - 1) * ew_max + j;
      if (!no_ns[i][j])
        dsu.funion(id, id + 1);
      if (!no_ew[i][j])
        dsu.funion(id, id + ew_max);
    }
  }
  int parent = dsu.find((ns_0 - 1) * ew_max + ew_0);
  long long ans = 0;
  for (int i = 1; i <= ns_max; ++i) {
    for (int j = 1, l = 0; j <= ew_max; ++j) {
      int id = (i - 1) * ew_max + j;
      if (dsu.find(id) == parent) {
        if (i == 1 || i == ns_max || j == 1 || j == ew_max) {
          ans = LLONG_MAX;
          goto end;
        }
        if (dsu.find(id + 1) != parent) {
          ans += (long long)(r_ns[i] - r_ns[i - 1]) *
                 (long long)(r_ew[j] - r_ew[l]);
        }
      } else
        l = j;
    }
  }
end:
  if (ans != LLONG_MAX)
    printf("%lld\n", ans);
  else
    printf("INF\n");
  return 0;
}