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

#include <bits/stdc++.h>
using namespace std;
#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define uniq(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string) { cout << endl; }
template <class H, class... T> void _dbg(string s, H h, T... t) {
  int l = s.find(',');
  cout << s.substr(0, l) << " = " << h << ", ";
  _dbg(s.substr(l + 1), t...);
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

#define INF 1120000000

class UnionFind {
public:
  vector<int> par,
      rank; // parent(negative := its root and abs-value is its size), depth
  UnionFind(int sz) : par(sz, -1), rank(sz, 0) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;                // already belong to same tree
    if (rank[x] < rank[y]) { // y becomes parent node
      par[y] += par[x];
      par[x] = y;
    } else { // x becomes parent node
      par[x] += par[y];
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -par[find(x)]; }
};

bool solve(int n) {
  vector<int> x(n), y(n);
  vector<char> dir(n);
  map<pair<int, int>, int> number;
  int cnt = 0;
  auto add = [&](int xx, int yy) {
    if (number.count(mp(xx, yy)) == 0)
      number[mp(xx, yy)] = cnt++;
  };
  rep(i, n) {
    char s[5];
    scanf("%d %d %s", &x[i], &y[i], s);
    dir[i] = s[0];
    add(x[i], y[i]);
    if (dir[i] == 'x')
      add(x[i] + 1, y[i]);
    else
      add(x[i], y[i] + 1);
  }

  UnionFind uf(2 * cnt);

  auto same = [&](int x1, int y1, int x2, int y2) {
    if (number.count(mp(x1, y1)) == 0 || number.count(mp(x2, y2)) == 0)
      return true;
    int n1 = number[mp(x1, y1)], n2 = number[mp(x2, y2)];
    uf.unite(n1, n2);
    uf.unite(n1 + cnt, n2 + cnt);
    if (uf.same(n1, n2 + cnt) || uf.same(n1 + cnt, n2))
      return false;
    return true;
  };
  auto diff = [&](int x1, int y1, int x2, int y2) {
    if (number.count(mp(x1, y1)) == 0 || number.count(mp(x2, y2)) == 0)
      return true;
    int n1 = number[mp(x1, y1)], n2 = number[mp(x2, y2)];
    uf.unite(n1, n2 + cnt);
    uf.unite(n1 + cnt, n2);
    if (uf.same(n1, n2) || uf.same(n1 + cnt, n2 + cnt))
      return false;
    return true;
  };

  rep(i, n) {
    if (dir[i] == 'x') {
      if (!same(x[i], y[i], x[i] - 1, y[i]) ||
          !same(x[i], y[i], x[i], y[i] + 1) ||
          !same(x[i], y[i], x[i], y[i] - 1) ||
          !same(x[i] + 1, y[i], x[i] + 2, y[i]) ||
          !same(x[i] + 1, y[i], x[i] + 1, y[i] + 1) ||
          !same(x[i] + 1, y[i], x[i] + 1, y[i] - 1) ||
          !diff(x[i], y[i], x[i] + 1, y[i]))
        return false;
    } else {
      if (!same(x[i], y[i], x[i] - 1, y[i]) ||
          !same(x[i], y[i], x[i] + 1, y[i]) ||
          !same(x[i], y[i], x[i], y[i] - 1) ||
          !same(x[i], y[i] + 1, x[i] + 1, y[i] + 1) ||
          !same(x[i], y[i] + 1, x[i] - 1, y[i] + 1) ||
          !same(x[i], y[i] + 1, x[i], y[i] + 2) ||
          !diff(x[i], y[i], x[i], y[i] + 1))
        return false;
    }
  }
  return true;
}

int main() {
  int n;
  while (cin >> n, n) {
    if (solve(n))
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define uniq(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string) { cout << endl; }
template <class H, class... T> void _dbg(string s, H h, T... t) {
  int l = s.find(',');
  cout << s.substr(0, l) << " = " << h << ", ";
  _dbg(s.substr(l + 1), t...);
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

#define INF 1120000000

class UnionFind {
public:
  vector<int> par,
      rank; // parent(negative := its root and abs-value is its size), depth
  UnionFind(int sz) : par(sz, -1), rank(sz, 0) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;                // already belong to same tree
    if (rank[x] < rank[y]) { // y becomes parent node
      par[y] += par[x];
      par[x] = y;
    } else { // x becomes parent node
      par[x] += par[y];
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -par[find(x)]; }
};

bool solve(int n) {
  vector<int> x(n), y(n), sx, sy;
  vector<char> dir(n);
  set<pair<int, int>> occ;
  rep(i, n) {
    char s[5];
    scanf("%d %d %s", &x[i], &y[i], s);
    dir[i] = s[0];
    sx.pb(x[i]);
    sx.pb(x[i] + 1);
    sx.pb(x[i] - 1);
    sy.pb(y[i]);
    sy.pb(y[i] + 1);
    sy.pb(y[i] - 1);
    if (dir[i] == 'x')
      sx.pb(x[i] + 2);
    else
      sy.pb(y[i] + 2);
  }
  uniq(sx);
  uniq(sy);
  int nx = sx.size();
  int ny = sy.size();
  rep(i, n) x[i] = lower_bound(all(sx), x[i]) - sx.begin();
  rep(i, n) y[i] = lower_bound(all(sy), y[i]) - sy.begin();
  rep(i, n) {
    occ.insert(mp(x[i], y[i]));
    if (dir[i] == 'x')
      occ.insert(mp(x[i] + 1, y[i]));
    else
      occ.insert(mp(x[i], y[i] + 1));
  }

  UnionFind uf(2 * nx * ny);

  auto same = [&](int x1, int y1, int x2, int y2) {
    if (occ.count(mp(x1, y1)) == 0 || occ.count(mp(x2, y2)) == 0)
      return true;
    int n1 = x1 * ny + y1, n2 = x2 * ny + y2;
    uf.unite(n1, n2);
    uf.unite(n1 + nx * ny, n2 + nx * ny);
    if (uf.same(n1, n2 + nx * ny) || uf.same(n1 + nx * ny, n2))
      return false;
    return true;
  };
  auto diff = [&](int x1, int y1, int x2, int y2) {
    if (occ.count(mp(x1, y1)) == 0 || occ.count(mp(x2, y2)) == 0)
      return true;
    int n1 = x1 * ny + y1, n2 = x2 * ny + y2;
    uf.unite(n1, n2 + nx * ny);
    uf.unite(n1 + nx * ny, n2);
    if (uf.same(n1, n2) || uf.same(n1 + nx * ny, n2 + nx * ny))
      return false;
    return true;
  };

  rep(i, n) {
    if (dir[i] == 'x') {
      if (!same(x[i], y[i], x[i] - 1, y[i]) ||
          !same(x[i], y[i], x[i], y[i] + 1) ||
          !same(x[i], y[i], x[i], y[i] - 1) ||
          !same(x[i] + 1, y[i], x[i] + 2, y[i]) ||
          !same(x[i] + 1, y[i], x[i] + 1, y[i] + 1) ||
          !same(x[i] + 1, y[i], x[i] + 1, y[i] - 1) ||
          !diff(x[i], y[i], x[i] + 1, y[i]))
        return false;
    } else {
      if (!same(x[i], y[i], x[i] - 1, y[i]) ||
          !same(x[i], y[i], x[i] + 1, y[i]) ||
          !same(x[i], y[i], x[i], y[i] - 1) ||
          !same(x[i], y[i] + 1, x[i] + 1, y[i] + 1) ||
          !same(x[i], y[i] + 1, x[i] - 1, y[i] + 1) ||
          !same(x[i], y[i] + 1, x[i], y[i] + 2) ||
          !diff(x[i], y[i], x[i], y[i] + 1))
        return false;
    }
  }
  return true;
}

int main() {
  int n;
  while (cin >> n, n) {
    if (solve(n))
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }

  return 0;
}