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

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

#define llong long long
#define len(x) ((int)x.size())
#define rep(i, n) for (int i = -1; ++i < n;)
#define rep1(i, n) for (int i = 0; i++ < n;)
#define rand __rand
mt19937 rng(
    chrono::system_clock::now().time_since_epoch().count()); // or mt19937_64
template <class T = int> T rand(T range = numeric_limits<T>::max()) {
  return (T)(rng() % range);
}

#define CONCAT_(x, y) x##y /*{{{*/
#define CONCAT(x, y) CONCAT_(x, y)
#ifdef LOCAL_DEBUG
int __db_level = 0;
bool __db_same_line = false;
#define clog cerr << string(!__db_same_line ? __db_level * 2 : 0, ' ')
struct debug_block {
  function<void()> fn;
  void print_name() {
    __db_same_line = true;
    fn();
    clog << endl;
    __db_same_line = false;
  }
  debug_block(function<void()> fn_) : fn(fn_) {
    clog << "{ ";
    print_name();
    ++__db_level;
  }
  ~debug_block() {
    --__db_level;
    clog << "} ";
    print_name();
  }
};
#define DB(args...) debug_block CONCAT(dbbl, __LINE__)([=] { clog << args; })
#define deb(...)                                                               \\
  if (1) {                                                                     \\
    (clog << "[" #__VA_ARGS__ "] = [" << __VA_ARGS__) << "]";                  \\
    if (!__db_same_line)                                                       \\
      clog << endl;                                                            \\
  }
#else
#define clog                                                                   \\
  if (0)                                                                       \\
  cerr
#define DB(...)
#define deb(...)
#endif
template <class T> ostream &operator,(ostream &out, const T &thing) {
  return out << ", " << thing;
}
template <class U, class V>
ostream &operator<<(ostream &out, const pair<U, V> &p) {
  return (out << "(" << p.first, p.second) << ")";
}
template <class A, class B>
ostream &operator<<(ostream &out, const tuple<A, B> &t) {
  return (out << "(" << get<0>(t), get<1>(t)) << ")";
}
template <class A, class B, class C>
ostream &operator<<(ostream &out, const tuple<A, B, C> &t) {
  return (out << "(" << get<0>(t), get<1>(t), get<2>(t)) << ")";
}
template <class T>
ostream &operator<<(ostream &out, const vector<T> &container) {
  out << "{";
  if (len(container))
    out << container[0];
  rep1(i, len(container) - 1) out, container[i];
  return out << "}";
}
template <class x> vector<typename x::value_type> $v(const x &a) {
  return vector<typename x::value_type>(a.begin(), a.end());
}
#define ptrtype(x) typename iterator_traits<x>::value_type
template <class u> vector<ptrtype(u)> $v(u a, u b) {
  return vector<ptrtype(u)>(a, b);
} /*}}}*/
// ACTUAL SOLUTION BELOW
// ////////////////////////////////////////////////////////////

const llong inf = (llong)(1e10);
int n;
map<llong, set<llong>> major_down, minor_down, major_up, minor_up;
map<llong, set<llong>> go_down, go_up, go_left, go_right;

int main(void) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  cin >> n;
  rep(i, n) {
    llong x, y;
    string dir;
    cin >> x >> y >> dir;
    switch (dir[0]) {
    case 'U':
      go_up[x].insert(y);
      major_up[x + y].insert(x);
      minor_up[x - y].insert(x);
      break;
    case 'D':
      go_down[x].insert(y);
      major_down[x + y].insert(x);
      minor_down[x - y].insert(x);
      break;
    case 'R':
      go_right[y].insert(x);
      break;
    case 'L':
      go_left[y].insert(x);
      break;
    }
  }

  llong ans = inf;

  auto upd_ans = [&](llong val) {
    assert(val > 0);
    ans = min(ans, val);
  };

  for (auto &[x, up] : go_up) {
    if (!go_down.count(x))
      continue;
    auto &down = go_down[x];
    for (auto &y : up) {
      auto oy = down.lower_bound(y);
      if (oy != down.end())
        upd_ans(5ll * (*oy - y));
    }
  }

  for (auto &[y, right] : go_right) {
    if (!go_left.count(y))
      continue;
    auto &left = go_left[y];
    for (auto &x : right) {
      auto ox = left.lower_bound(x);
      if (ox != left.end())
        upd_ans(5ll * (*ox - x));
    }
  }

  for (auto &[y, right] : go_right)
    for (auto x : right) {
      auto md = minor_down.find(x - y);
      if (md != minor_down.end()) {
        auto ox = md->second.lower_bound(x);
        if (ox != md->second.end())
          upd_ans((*ox - x) * 10LL);
      }

      auto mu = major_up.find(x + y);
      if (mu != major_up.end()) {
        auto ox = mu->second.lower_bound(x);
        if (ox != mu->second.end())
          upd_ans((*ox - x) * 10LL);
      }
    }

  for (auto &[y, left] : go_left)
    for (auto x : left) {
      auto md = major_down.find(x + y);
      if (md != major_down.end()) {
        auto ox = md->second.upper_bound(x);
        if (ox != md->second.begin())
          upd_ans((x - *--ox) * 10LL);
      }

      auto mu = minor_up.find(x - y);
      if (mu != minor_up.end()) {
        auto ox = mu->second.upper_bound(x);
        if (ox != mu->second.begin())
          upd_ans((x - *--ox) * 10LL);
      }
    }

  if (ans >= inf)
    cout << "SAFE";
  else
    cout << ans;

  return 0;
}

// Remember:
// - Multitest? REFRESHING the data!!!
// - Constrains for each set of data may differs. Should NOT USE the same max
// constant (maxn)
//   for all of them.
// vim: foldmethod=marker


Error: WA

Fixed submission:

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

#define llong long long
#define len(x) ((int)x.size())
#define rep(i, n) for (int i = -1; ++i < n;)
#define rep1(i, n) for (int i = 0; i++ < n;)
#define rand __rand
mt19937 rng(
    chrono::system_clock::now().time_since_epoch().count()); // or mt19937_64
template <class T = int> T rand(T range = numeric_limits<T>::max()) {
  return (T)(rng() % range);
}

#define CONCAT_(x, y) x##y /*{{{*/
#define CONCAT(x, y) CONCAT_(x, y)
#ifdef LOCAL_DEBUG
int __db_level = 0;
bool __db_same_line = false;
#define clog cerr << string(!__db_same_line ? __db_level * 2 : 0, ' ')
struct debug_block {
  function<void()> fn;
  void print_name() {
    __db_same_line = true;
    fn();
    clog << endl;
    __db_same_line = false;
  }
  debug_block(function<void()> fn_) : fn(fn_) {
    clog << "{ ";
    print_name();
    ++__db_level;
  }
  ~debug_block() {
    --__db_level;
    clog << "} ";
    print_name();
  }
};
#define DB(args...) debug_block CONCAT(dbbl, __LINE__)([=] { clog << args; })
#define deb(...)                                                               \\
  if (1) {                                                                     \\
    (clog << "[" #__VA_ARGS__ "] = [" << __VA_ARGS__) << "]";                  \\
    if (!__db_same_line)                                                       \\
      clog << endl;                                                            \\
  }
#else
#define clog                                                                   \\
  if (0)                                                                       \\
  cerr
#define DB(...)
#define deb(...)
#endif
template <class T> ostream &operator,(ostream &out, const T &thing) {
  return out << ", " << thing;
}
template <class U, class V>
ostream &operator<<(ostream &out, const pair<U, V> &p) {
  return (out << "(" << p.first, p.second) << ")";
}
template <class A, class B>
ostream &operator<<(ostream &out, const tuple<A, B> &t) {
  return (out << "(" << get<0>(t), get<1>(t)) << ")";
}
template <class A, class B, class C>
ostream &operator<<(ostream &out, const tuple<A, B, C> &t) {
  return (out << "(" << get<0>(t), get<1>(t), get<2>(t)) << ")";
}
template <class T>
ostream &operator<<(ostream &out, const vector<T> &container) {
  out << "{";
  if (len(container))
    out << container[0];
  rep1(i, len(container) - 1) out, container[i];
  return out << "}";
}
template <class x> vector<typename x::value_type> $v(const x &a) {
  return vector<typename x::value_type>(a.begin(), a.end());
}
#define ptrtype(x) typename iterator_traits<x>::value_type
template <class u> vector<ptrtype(u)> $v(u a, u b) {
  return vector<ptrtype(u)>(a, b);
} /*}}}*/
// ACTUAL SOLUTION BELOW
// ////////////////////////////////////////////////////////////

const llong inf = (llong)(1e10);
int n;
map<int, set<int>> major_down, minor_down, major_up, minor_up;
map<int, int> max_down, min_up, max_left, min_right;

vector<pair<int, int>> go_left, go_right;

int main(void) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  cin >> n;
  rep(i, n) {
    int x, y;
    char dir;
    cin >> x >> y >> dir;
    switch (dir) {
    case 'U':
      if (!min_up.count(x))
        min_up[x] = y;
      else
        min_up[x] = min(min_up[x], y);
      major_up[x + y].insert(x);
      minor_up[x - y].insert(x);
      deb(x, y + 10);
      break;
    case 'D':
      if (!max_down.count(x))
        max_down[x] = y;
      else
        max_down[x] = max(max_down[x], y);
      major_down[x + y].insert(x);
      minor_down[x - y].insert(x);
      deb(x, y - 10);
      break;
    case 'R':
      if (!min_right.count(y))
        min_right[y] = x;
      else
        min_right[y] = min(min_right[y], x);
      go_right.emplace_back(x, y);
      deb(x + 10, y);
      break;
    case 'L':
      if (!max_left.count(y))
        max_left[y] = x;
      else
        max_left[y] = max(max_left[y], x);
      go_left.emplace_back(x, y);
      deb(x - 10, y);
      break;
    }
    // deb(x + y, x - y);
  }

  llong ans = inf;

  auto upd_ans = [&](llong val) {
    deb(val);
    assert(val > 0);
    ans = min(ans, val);
  };

  clog << "ver check" << endl;
  for (auto [x, y] : min_up) {
    if (max_down.count(x) and max_down[x] > y) {
      upd_ans(5LL * (max_down[x] - y));
    }
  }

  clog << "hor check" << endl;
  for (auto [y, x] : min_right) {
    if (max_left.count(y) and max_left[y] > x) {
      upd_ans(5LL * (max_left[y] - x));
    }
  }

  for (auto &[r, s] : major_down) {
    deb(r, $v(s));
  }

  clog << "right-ver check" << endl;
  for (auto [x, y] : go_right) {
    auto md = minor_down.find(x - y);
    auto mu = major_up.find(x + y);

    if (md != minor_down.end()) {
      auto ox = md->second.lower_bound(x);
      if (ox != md->second.end())
        upd_ans((*ox - x) * 10LL);
    }
    if (mu != major_up.end()) {
      auto ox = mu->second.lower_bound(x);
      if (ox != mu->second.end())
        upd_ans((*ox - x) * 10LL);
    }
  }

  clog << "left-ver check" << endl;
  for (auto [x, y] : go_left) {
    DB(""; deb(x, y, x + y, x - y));
    auto md = major_down.find(x + y);
    auto mu = minor_up.find(x - y);

    if (md != major_down.end()) {
      deb($v(md->second));
      auto ox = md->second.upper_bound(x);
      if (ox != md->second.begin())
        upd_ans((x - *--ox) * 10LL);
    }
    if (mu != minor_up.end()) {
      auto ox = mu->second.upper_bound(x);
      if (ox != mu->second.begin())
        upd_ans((x - *--ox) * 10LL);
    }
  }

  assert(ans < inf);
  if (ans >= inf)
    cout << "SAFE";
  else
    cout << ans;

  return 0;
}

// Remember:
// - Multitest? REFRESHING the data!!!
// - Constrains for each set of data may differs. Should NOT USE the same max
// constant (maxn)
//   for all of them.
// vim: foldmethod=marker