Problem p03753 (C++)

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

template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}

struct UnionFind {
  Int n;
  vector<Int> r, p;
  UnionFind() {}
  UnionFind(Int sz) : n(sz), r(sz, 1), p(sz, 0) { iota(p.begin(), p.end(), 0); }
  Int find(Int x) { return (x == p[x] ? x : p[x] = find(p[x])); }
  bool same(Int x, Int y) { return find(x) == find(y); }
  void unite(Int x, Int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }
};

// INSERT ABOVE HERE
signed main() {
  Int n, m, q;
  cin >> n >> m >> q;
  vector<Int> a(q);
  for (Int i = 0; i < q; i++)
    cin >> a[i];
  vector<Int> d(m, 0);
  for (Int i = 0; i < q; i++)
    d[a[i]] = 1;

  Int w = 7, h = (m % 7 ? m : m / 7);
  Int dy[] = {0, 0, 1, -1};
  Int dx[] = {1, -1, 0, 0};
  auto in = [&](Int y, Int x) { return 0 <= y && y < h && 0 <= x && x < w; };

  auto dp = make_v<Int>(h, w);
  fill_v(dp, -1);

  auto idx = [&](Int y, Int x) { return y * w + x; };

  auto bfs = [&](Int y, Int x, Int p) {
    using P = pair<Int, Int>;
    queue<P> q;
    dp[y][x] = p;
    q.emplace(y, x);
    while (!q.empty()) {
      tie(y, x) = q.front();
      q.pop();
      for (Int k = 0; k < 4; k++) {
        Int ny = y + dy[k], nx = x + dx[k];
        if (!in(ny, nx) || d[idx(ny, nx)] || ~dp[ny][nx])
          continue;
        dp[ny][nx] = p;
        q.emplace(ny, nx);
      }
    }
  };

  Int cnt = 0;
  for (Int i = 0; i < h; i++)
    for (Int j = 0; j < w; j++)
      if (!d[idx(i, j)] && !~dp[i][j])
        bfs(i, j, cnt++);

  Int ans = cnt;
  Int num = n / h - 1;
  UnionFind uf(cnt * 2);
  for (Int j = 0; j < w; j++)
    if (~dp[0][j] && ~dp[h - 1][j])
      uf.unite(dp[0][j], cnt + dp[h - 1][j]);

  Int dif = -cnt;
  for (Int i = 0; i < cnt * 2; i++)
    if (uf.find(i) == i)
      dif++;

  ans += dif * num;
  cout << ans << endl;
  return 0;
}


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

template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}

struct UnionFind {
  Int n;
  vector<Int> r, p;
  UnionFind() {}
  UnionFind(Int sz) : n(sz), r(sz, 1), p(sz, 0) { iota(p.begin(), p.end(), 0); }
  Int find(Int x) { return (x == p[x] ? x : p[x] = find(p[x])); }
  bool same(Int x, Int y) { return find(x) == find(y); }
  void unite(Int x, Int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }
};

// INSERT ABOVE HERE
signed main() {
  Int n, m, q;
  cin >> n >> m >> q;
  vector<Int> a(q);
  for (Int i = 0; i < q; i++)
    cin >> a[i];
  vector<Int> d(m, 0);
  for (Int i = 0; i < q; i++)
    d[a[i]] = 1;

  Int w = 7, h = (m % 7 ? m : m / 7);
  Int dy[] = {0, 0, 1, -1};
  Int dx[] = {1, -1, 0, 0};
  auto in = [&](Int y, Int x) { return 0 <= y && y < h && 0 <= x && x < w; };

  auto dp = make_v<Int>(h, w);
  fill_v(dp, -1);

  auto idx = [&](Int y, Int x) { return (y * w + x) % m; };

  auto bfs = [&](Int y, Int x, Int p) {
    using P = pair<Int, Int>;
    queue<P> q;
    dp[y][x] = p;
    q.emplace(y, x);
    while (!q.empty()) {
      tie(y, x) = q.front();
      q.pop();
      for (Int k = 0; k < 4; k++) {
        Int ny = y + dy[k], nx = x + dx[k];
        if (!in(ny, nx) || d[idx(ny, nx)] || ~dp[ny][nx])
          continue;
        dp[ny][nx] = p;
        q.emplace(ny, nx);
      }
    }
  };

  Int cnt = 0;
  for (Int i = 0; i < h; i++)
    for (Int j = 0; j < w; j++)
      if (!d[idx(i, j)] && !~dp[i][j])
        bfs(i, j, cnt++);

  Int ans = cnt;
  Int num = n / h - 1;
  UnionFind uf(cnt * 2);
  for (Int j = 0; j < w; j++)
    if (~dp[0][j] && ~dp[h - 1][j])
      uf.unite(dp[0][j], cnt + dp[h - 1][j]);

  Int dif = -cnt;
  for (Int i = 0; i < cnt * 2; i++)
    if (uf.find(i) == i)
      dif++;

  ans += dif * num;
  cout << ans << endl;
  return 0;
}