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

#include <bits/stdc++.h>

using namespace std;

#define SZ(x) (int)(x.size())
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RREP(i, n) for (int i = (int)(n); i >= 0; --i)
#define RFOR(i, a, b) for (int i = (int)(a); i >= (int)(b); --i)
#define ALL(a) (a).begin(), (a).end()
#define DUMP(x) cerr << #x << " = " << (x) << endl
#define DEBUG(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;

const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;

template <typename T1, typename T2> bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T1, typename T2> bool chmin(T1 &a, const T2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  REP(i, SZ(v)) {
    if (i)
      os << " ";
    os << v[i];
  }
  return os;
}

struct Elm {
  int r, c;
  int d1, d2;
  int dir;
};

bool operator<(Elm e1, Elm e2) {
  return tuple<int, int, int, int, int>(e1.d1, e1.d2, e1.r, e1.c, e1.dir) <
         tuple<int, int, int, int, int>(e2.d1, e2.d2, e2.r, e2.c, e2.dir);
}

bool operator>(Elm e1, Elm e2) { return !(e1 < e2); }

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  ll h, w, k;
  cin >> h >> w >> k;
  P st, gl;
  cin >> st.first >> st.second;
  cin >> gl.first >> gl.second;
  st.first--;
  st.second--;
  gl.first--;
  gl.second--;
  vector<vector<bool>> g(h, vector<bool>(w));
  REP(i, h) {
    REP(j, w) {
      char c;
      cin >> c;
      g[i][j] = c == '.';
    }
  }

  priority_queue<Elm, vector<Elm>, greater<Elm>> pq;
  vector<vector<vector<P>>> d(h,
                              vector<vector<P>>(w, vector<P>(4, {INF, INF})));
  pq.push({st.first, st.second, 0, 0, 0});
  pq.push({st.first, st.second, 0, 0, 1});
  pq.push({st.first, st.second, 0, 0, 2});
  pq.push({st.first, st.second, 0, 0, 3});

  d[st.first][st.second][0] = {0, 0};
  d[st.first][st.second][1] = {0, 0};
  d[st.first][st.second][2] = {0, 0};
  d[st.first][st.second][3] = {0, 0};

  vi dr = {0, 1, 0, -1};
  vi dc = {1, 0, -1, 0};

  while (!pq.empty()) {
    auto now = pq.top();
    pq.pop();

    int nr = now.r + dr[now.dir], nc = now.c + dc[now.dir];
    if (0 <= nr && nr < h && 0 <= nc && nc < w && g[nr][nc]) {
      int nd1 = now.d1, nd2 = now.d2 + 1;
      if (nd2 == k) {
        nd1++;
        nd2 = 0;
      }

      if (d[nr][nc][now.dir] > make_pair(nd1, nd2)) {
        d[nr][nc][now.dir] = make_pair(nd1, nd2);
        pq.push({nr, nc, nd1, nd2, now.dir});
      }
    }

    int nd1 = now.d1 + (now.d2 != 0);

    if (d[now.r][now.c][(now.dir + 1) % 4] > make_pair(nd1, 0)) {
      d[now.r][now.c][(now.dir + 1) % 4] = make_pair(nd1, 0);
      pq.push({now.r, now.c, nd1, 0, (now.dir + 1) % 4});
    }

    if (d[now.r][now.c][(now.dir + 3) % 4] > make_pair(nd1, 0)) {
      d[now.r][now.c][(now.dir + 3) % 4] = make_pair(nd1, 0);
      pq.push({now.r, now.c, nd1, 0, (now.dir + 3) % 4});
    }
  }

  int ans = INF;
  REP(i, 4) {
    chmin(ans, d[gl.first][gl.second][i].first +
                   (d[gl.first][gl.second][i].second != 0));
  }
  cout << (ans == INF ? -1 : ans) << endl;
}


Error: WA

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define SZ(x) (int)(x.size())
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RREP(i, n) for (int i = (int)(n); i >= 0; --i)
#define RFOR(i, a, b) for (int i = (int)(a); i >= (int)(b); --i)
#define ALL(a) (a).begin(), (a).end()
#define DUMP(x) cerr << #x << " = " << (x) << endl
#define DEBUG(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;

const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;

template <typename T1, typename T2> bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T1, typename T2> bool chmin(T1 &a, const T2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  REP(i, SZ(v)) {
    if (i)
      os << " ";
    os << v[i];
  }
  return os;
}

#define N 10003

class SegmentTree {
  const ll inf = 1e18;
  int n, n0;
  ll max_v[4 * N], smax_v[4 * N];
  ll sum[4 * N], max_c[4 * N];

  void update_node_max(int k, ll x) {
    sum[k] += (x - max_v[k]) * max_c[k];
    max_v[k] = x;
  }

  void push(int k) {
    if (max_v[k] < max_v[2 * k + 1]) {
      update_node_max(2 * k + 1, max_v[k]);
    }
    if (max_v[k] < max_v[2 * k + 2]) {
      update_node_max(2 * k + 2, max_v[k]);
    }
  }

  void update(int k) {
    sum[k] = sum[2 * k + 1] + sum[2 * k + 2];

    if (max_v[2 * k + 1] < max_v[2 * k + 2]) {
      max_v[k] = max_v[2 * k + 2];
      max_c[k] = max_c[2 * k + 2];
      smax_v[k] = max(max_v[2 * k + 1], smax_v[2 * k + 2]);
    } else if (max_v[2 * k + 1] > max_v[2 * k + 2]) {
      max_v[k] = max_v[2 * k + 1];
      max_c[k] = max_c[2 * k + 1];
      smax_v[k] = max(smax_v[2 * k + 1], max_v[2 * k + 2]);
    } else {
      max_v[k] = max_v[2 * k + 1];
      max_c[k] = max_c[2 * k + 1] + max_c[2 * k + 2];
      smax_v[k] = max(smax_v[2 * k + 1], smax_v[2 * k + 2]);
    }
  }

  void _update_min(ll x, int a, int b, int k, int l, int r) {
    if (b <= l || r <= a || max_v[k] <= x) {
      return;
    }
    if (a <= l && r <= b && smax_v[k] < x) {
      update_node_max(k, x);
      return;
    }

    push(k);
    _update_min(x, a, b, 2 * k + 1, l, (l + r) / 2);
    _update_min(x, a, b, 2 * k + 2, (l + r) / 2, r);
    update(k);
  }

  ll _query_max(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a) {
      return 0;
    }
    if (a <= l && r <= b) {
      return max_v[k];
    }
    push(k);
    ll lv = _query_max(a, b, 2 * k + 1, l, (l + r) / 2);
    ll rv = _query_max(a, b, 2 * k + 2, (l + r) / 2, r);
    return max(lv, rv);
  }

  ll _query_sum(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a) {
      return 0;
    }
    if (a <= l && r <= b) {
      return sum[k];
    }
    push(k);
    ll lv = _query_sum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll rv = _query_sum(a, b, 2 * k + 2, (l + r) / 2, r);
    return lv + rv;
  }

public:
  SegmentTree(int n) { SegmentTree(n, vll(n)); }

  SegmentTree(int n, vll a) : n(n) {
    n0 = 1;
    while (n0 < n)
      n0 <<= 1;

    for (int i = 0; i < n; ++i) {
      max_v[n0 - 1 + i] = sum[n0 - 1 + i] = a[i];
      smax_v[n0 - 1 + i] = -inf;
      max_c[n0 - 1 + i] = 1;
    }

    for (int i = n; i < n0; ++i) {
      max_v[n0 - 1 + i] = smax_v[n0 - 1 + i] = -inf;
      sum[n0 - 1 + i] = max_c[n0 - 1 + i] = 0;
    }
    for (int i = n0 - 2; i >= 0; i--)
      update(i);
  }

  // range minimize query
  void update_min(int a, int b, ll x) { return _update_min(x, a, b, 0, 0, n0); }

  // range maximum query
  ll query_max(int a, int b) { return _query_max(a, b, 0, 0, n0); }

  // range sum query
  ll query_sum(int a, int b) { return _query_sum(a, b, 0, 0, n0); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  int h, w, k;
  cin >> h >> w >> k;
  P st, ed;
  cin >> st.first >> st.second >> ed.first >> ed.second;
  st.first--;
  st.second--;
  ed.first--;
  ed.second--;

  vector<string> v(h);
  REP(i, h) { cin >> v[i]; }

  if (h > w) {
    swap(st.first, st.second);
    swap(ed.first, ed.second);
    vector<string> v2(w);
    REP(i, w) {
      REP(j, h) { v2[i].push_back(v[j][i]); }
    }
    v = v2;
    swap(h, w);
  }

  vvi hasu(h);
  REP(i, h) {
    REP(j, w) {
      if (v[i][j] == '@') {
        hasu[i].push_back(j);
      }
    }
  }

  vector<P> pos;
  map<P, bool> sel;
  queue<P> que;
  pos.push_back(st);
  sel[st] = true;
  que.push(st);
  vi dr = {-1, 1, 0, 0};
  vi dc = {0, 0, -1, 1};
  while (!que.empty()) {
    int r, c;
    tie(r, c) = que.front();
    que.pop();
    REP(i, 4) {
      int nr = r + dr[i];
      int nc = c + dc[i];
      if (!(0 <= nr && nr < h && 0 <= nc && nc < w))
        continue;
      if (v[nr][nc] == '@')
        continue;
      if (sel[{nr, nc}])
        continue;
      sel[{nr, nc}] = true;
      pos.push_back({nr, nc});
      que.push({nr, nc});
    }
  }

  vll init(w, LINF);
  vector<SegmentTree> segtree(h, SegmentTree(w, init));
  segtree[st.first].update_min(st.second, st.second + 1, 0);

  REP(i, SZ(pos)) {
    int r, c;
    tie(r, c) = pos[i];
    int val = segtree[r].query_max(c, c + 1);
    REP(j, 2){FOR(l, 1, k + 1){int nr = r + dr[j] * l;
    if (!(0 <= nr && nr < h))
      break;
    if (v[nr][c] == '@') {
      break;
    }
    segtree[nr].update_min(c, c + 1, val + 1);
  }
}

{
  auto it = upper_bound(ALL(hasu[r]), c);
  int nxthasu = INF;
  if (it != hasu[r].end())
    nxthasu = *it;
  segtree[r].update_min(c + 1, min(nxthasu, c + k + 1), val + 1);
}

{
  auto it = lower_bound(ALL(hasu[r]), c);
  int nxthasu = INF;
  if (it != hasu[r].begin()) {
    it--;
    nxthasu = *it;
  }
  segtree[r].update_min(max(nxthasu + 1, c - k), c, val + 1);
}
}

auto ans = segtree[ed.first].query_max(ed.second, ed.second + 1);

cout << (ans >= INF ? -1 : ans) << endl;
}