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

#include <bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(), x.end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define debug(v)                                                               \\
  cout << #v << ":";                                                           \\
  for (auto x : v) {                                                           \\
    cout << x << ' ';                                                          \\
  }                                                                            \\
  cout << endl;
#define INF 1000000000
#define mod 1000000007
using ll = long long;
const ll LINF = 1001002003004005006ll;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  int sz;
  vector<Monoid> seg;
  const F f;
  const Monoid gen;
  SegmentTree(int n, const F f, const Monoid &gen) : f(f), gen(gen) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, gen);
  }
  void set(int k, const Monoid &x) { seg[k + sz] = x; }
  void build() {
    for (int k = sz - 1; k > 0; k--)
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
  }
  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1)
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
  }
  // [a,b)
  Monoid query(int a, int b) {
    Monoid L = gen, R = gen;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }
  Monoid operator[](const int &k) const { return seg[k + sz]; }
};
int f(int a, int b) { return a < b ? a : b; }

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int h, w, k;
  cin >> h >> w >> k;
  int sh, sw, gh, gw;
  cin >> sh >> sw >> gh >> gw;
  sh--, sw--, gh--, gw--;
  string s[h];
  rep(i, h) cin >> s[i];

  set<int> state[w], syoko[h];
  rep(i, h) {
    syoko[i].insert(-1);
    syoko[i].insert(w);
  }
  rep(i, w) {
    state[i].insert(-1);
    state[i].insert(h);
  }
  rep(i, h) {
    rep(j, w) {
      if (s[i][j] == '@') {
        state[j].insert(i);
        syoko[i].insert(j);
      }
    }
  }

  vector<SegmentTree<int>> segtate, segyoko;
  rep(i, w) {
    SegmentTree<int> seg(h, f, INF);
    seg.build();
    segtate.push_back(seg);
  }
  rep(j, h) {
    SegmentTree<int> seg(w, f, INF);
    seg.build();
    segyoko.push_back(seg);
  }

  segtate[sw].update(sh, 0);
  segyoko[sh].update(sw, 0);

  priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>,
                 greater<pair<int, pair<int, int>>>>
      que;
  int ans[h][w];
  int check[h][w];
  rep(i, h) rep(j, w) ans[i][j] = INF, check[i][j] = false;
  ans[sh][sw] = 0;
  check[sh][sw] = true;
  auto unko = [&](int ui, int uj) {
    return 0 <= ui and ui < h and 0 <= uj and uj < w and s[ui][uj] != '@';
  };
  rep(k, 4) {
    int ni = sh + dx[k], nj = sw + dy[k];
    if (unko(ni, nj)) {
      que.push({0, {ni, nj}});
      check[ni][nj] = true;
    }
  }
  while (!que.empty()) {
    auto p = que.top();
    que.pop();
    int i = p.second.first, j = p.second.second;

    // cout<<i<<" "<<j<<endl;
    // rep(i,h){
    //     rep(j,w){
    //         if(ans[i][j]==INF){
    //             cout<<"I ";
    //         }else{
    //             cout<<ans[i][j]<<" ";
    //         }
    //     }
    //     cout<<endl;
    // }

    int res = INF;
    // 左右
    {
      auto ite = syoko[i].lower_bound(j);
      int l = *prev(ite) + 1;
      int r = *ite - 1;
      l = max(l, j - k);
      r = min(r, j + k);
      chmin(res, segyoko[i].query(l, r + 1));
    }
    // 上下
    {
      auto ite = state[j].lower_bound(i);
      int d = *prev(ite) + 1;
      int u = *ite - 1;
      d = max(d, i - k);
      u = min(u, i + k);
      chmin(res, segtate[j].query(d, u + 1));
    }
    res++;

    if (chmin(ans[i][j], res)) {
      segtate[j].update(i, ans[i][j]);
      segyoko[i].update(j, ans[i][j]);
      rep(k, 4) {
        int ni = i + dx[k], nj = j + dy[k];
        if (unko(ni, nj)) {
          que.push({ans[i][j], {ni, nj}});
          check[ni][nj] = true;
        }
      }
    }
  }

  if (ans[gh][gw] >= INF)
    cout << -1 << endl;
  else
    cout << ans[gh][gw] << endl;
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(), x.end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define debug(v)                                                               \\
  cout << #v << ":";                                                           \\
  for (auto x : v) {                                                           \\
    cout << x << ' ';                                                          \\
  }                                                                            \\
  cout << endl;
#define INF 1000000000
#define mod 1000000007
using ll = long long;
const ll LINF = 1001002003004005006ll;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  int sz;
  vector<Monoid> seg;
  const F f;
  const Monoid gen;
  SegmentTree(int n, const F f, const Monoid &gen) : f(f), gen(gen) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, gen);
  }
  void set(int k, const Monoid &x) { seg[k + sz] = x; }
  void build() {
    for (int k = sz - 1; k > 0; k--)
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
  }
  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1)
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
  }
  // [a,b)
  Monoid query(int a, int b) {
    Monoid L = gen, R = gen;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }
  Monoid operator[](const int &k) const { return seg[k + sz]; }
};
int f(int a, int b) { return a < b ? a : b; }

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  int h, w, k;
  cin >> h >> w >> k;
  int sh, sw, gh, gw;
  cin >> sh >> sw >> gh >> gw;
  sh--, sw--, gh--, gw--;
  string s[h];
  rep(i, h) cin >> s[i];

  set<int> state[w], syoko[h];
  rep(i, h) {
    syoko[i].insert(-1);
    syoko[i].insert(w);
  }
  rep(i, w) {
    state[i].insert(-1);
    state[i].insert(h);
  }
  rep(i, h) {
    rep(j, w) {
      if (s[i][j] == '@') {
        state[j].insert(i);
        syoko[i].insert(j);
      }
    }
  }

  vector<SegmentTree<int>> segtate, segyoko;
  rep(i, w) {
    SegmentTree<int> seg(h, f, INF);
    seg.build();
    segtate.push_back(seg);
  }
  rep(j, h) {
    SegmentTree<int> seg(w, f, INF);
    seg.build();
    segyoko.push_back(seg);
  }

  segtate[sw].update(sh, 0);
  segyoko[sh].update(sw, 0);

  priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>,
                 greater<pair<int, pair<int, int>>>>
      que;
  int ans[h][w];
  int check[h][w];
  rep(i, h) rep(j, w) ans[i][j] = INF, check[i][j] = false;
  ans[sh][sw] = 0;
  auto unko = [&](int ui, int uj) {
    return 0 <= ui and ui < h and 0 <= uj and uj < w and s[ui][uj] != '@';
  };
  rep(k, 4) {
    int ni = sh + dx[k], nj = sw + dy[k];
    if (unko(ni, nj)) {
      que.push({0, {ni, nj}});
      check[ni][nj] = true;
    }
  }
  check[sh][sw] = true;

  while (!que.empty()) {
    auto p = que.top();
    que.pop();
    int i = p.second.first, j = p.second.second;

    // cout<<i<<" "<<j<<endl;
    // rep(i,h){
    //     rep(j,w){
    //         if(ans[i][j]==INF){
    //             cout<<"I ";
    //         }else{
    //             cout<<ans[i][j]<<" ";
    //         }
    //     }
    //     cout<<endl;
    // }

    int res = INF;
    // 左右
    {
      auto ite = syoko[i].lower_bound(j);
      int l = *prev(ite) + 1;
      int r = *ite - 1;
      l = max(l, j - k);
      r = min(r, j + k);
      chmin(res, segyoko[i].query(l, r + 1));
    }
    // 上下
    {
      auto ite = state[j].lower_bound(i);
      int d = *prev(ite) + 1;
      int u = *ite - 1;
      d = max(d, i - k);
      u = min(u, i + k);
      chmin(res, segtate[j].query(d, u + 1));
    }
    res++;
    ans[i][j] = min(ans[i][j], res);
    segtate[j].update(i, ans[i][j]);
    segyoko[i].update(j, ans[i][j]);

    rep(k, 4) {
      int ni = i + dx[k], nj = j + dy[k];
      if (unko(ni, nj) and !check[ni][nj]) {
        que.push({ans[i][j], {ni, nj}});
        check[ni][nj] = true;
      }
    }
  }

  if (ans[gh][gw] >= INF)
    assert(false); // cout<<-1<<endl;
  else
    cout << ans[gh][gw] << endl;
  return 0;
}