Problem p02644 (C++) — buggy submission, verdict: Time Limit Exceeded

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <random>
#include <unordered_map>
#include <unordered_set>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)((a).size())
#define heap priority_queue
#define hash_map unordered_map
#define hash_set unordered_set
#define ft first
#define sd second
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define endl "\\n"
#define die(cond)                                                              \\
  if (cond)                                                                    \\
    for (;;) {                                                                 \\
    }
#define y1 y_1
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef vector<ll> vll;
typedef set<ll> sll;
typedef map<ll, ll> mll;
const ll inf = numeric_limits<ll>::max() / 2;
const ld eps = 1e-9;
const ld pi = acos(-1);
template <typename T> inline bool mineq(T &a, T b) {
  return (a > b) ? (a = b, 1) : 0;
}
template <typename T> inline bool maxeq(T &a, T b) {
  return (a < b) ? (a = b, 1) : 0;
}

inline void solve(), read();
const string file = "";

int main() {
#ifndef _DEBUG
  if (file != "") {
    freopen((file + ".in").c_str(), "r", stdin);
    freopen((file + ".out").c_str(), "w", stdout);
  }
#endif
  fast;
  read();
  solve();
  return 0;
}

pll operator+(pll a, pll b) { return {a.ft + b.ft, a.sd + b.sd}; }

ll n, m, k;
vector<vll> a;
pll s, t;
vector<pll> dirs = {{0, -1}, {0, +1}, {-1, 0}, {+1, 0}};
vector<sll> vis1, vis2;

ll good(ll x, ll y) { return 0 <= x && x < n && 0 <= y && y < m && a[x][y]; }

ll bfs(pll s, pll t) {
  vis1.resize(n);
  vis2.resize(m);
  for (ll i = 0; i < n; i++) {
    for (ll j = 0; j < m; j++) {
      vis1[i].insert(j);
      vis2[j].insert(i);
    }
  }
  vis1[s.ft].erase(s.sd);
  vis2[s.sd].erase(s.ft);
  queue<pll> q;
  map<pll, ll> d;
  q.push(s);
  d[s] = 0;
  while (!q.empty()) {
    pll p = q.front();
    q.pop();
    sll::iterator i1;
    i1 = vis1[p.ft].lower_bound(p.sd);
    for (auto it = i1; it != vis1[p.ft].end() && *it <= p.sd + k;) {
      if (!a[p.ft][*it]) {
        break;
      }
      d[{p.ft, *it}] = d[p] + 1;
      q.push({p.ft, *it});
      vis2[*it].erase(p.ft);
      it = vis1[p.ft].erase(it);
    }
    i1 = vis1[p.ft].lower_bound(p.sd);
    if (i1 != vis1[p.ft].begin()) {
      --i1;
    }
    for (auto it = i1;
         it != vis1[p.ft].end() && *it < p.sd && p.sd - k <= *it;) {
      if (!a[p.ft][*it]) {
        break;
      }
      d[{p.ft, *it}] = d[p] + 1;
      q.push({p.ft, *it});
      vis2[*it].erase(p.ft);
      it = vis1[p.ft].erase(it);
      if (it == vis1[p.ft].begin()) {
        break;
      }
      --it;
    }
    i1 = vis2[p.sd].lower_bound(p.ft);
    for (auto it = i1; it != vis2[p.sd].end() && *it <= p.ft + k;) {
      if (!a[*it][p.sd]) {
        break;
      }
      d[{*it, p.sd}] = d[p] + 1;
      q.push({*it, p.sd});
      vis1[*it].erase(p.sd);
      it = vis2[p.sd].erase(it);
    }
    i1 = vis2[p.sd].lower_bound(p.ft);
    if (i1 != vis2[p.sd].begin()) {
      --i1;
    }
    for (auto it = i1;
         i1 != vis2[p.sd].end() && *it < p.ft && p.ft - k <= *it;) {
      if (!a[*it][p.sd]) {
        break;
      }
      d[{*it, p.sd}] = d[p] + 1;
      q.push({*it, p.sd});
      vis1[*it].erase(p.sd);
      it = vis2[p.sd].erase(it);
      if (it == vis2[p.sd].begin()) {
        break;
      }
      --it;
    }
  }
  if (!d.count(t)) {
    return -1;
  }
  return d[t];
}

inline void solve() {
  ll ans = bfs(s, t);
  cout << ans << endl;
}

inline void read() {
  cin >> n >> m >> k;
  a.resize(n, vll(m, 0));
  cin >> s.ft >> s.sd >> t.ft >> t.sd;
  --s.ft, --s.sd, --t.ft, --t.sd;
  for (ll i = 0; i < n; i++) {
    for (ll j = 0; j < m; j++) {
      char c;
      cin >> c;
      if (c == '.') {
        a[i][j] = 1;
      }
    }
  }
}

Error: TLE

Fixed submission:

// (c) 2020, redotter
// The grass was greener...

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
#pragma comment(linker, "/stack:200000000")
#endif

#define pb push_back
#define the(a) (a).begin(), (a).end()
#define ft first
#define sd second
#define endl "\\n"
#define forn(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define y1 y11

using i64 = int;
using i32 = int;
using f64 = double;

template <class T> using vec = vector<T>;
using str = string;
using p64 = pair<i64, i64>;
using v64 = vec<i64>;
using vv64 = vec<v64>;
using s64 = set<i64>;
using m64 = map<i64, i64>;
template <size_t Size1> using a64 = array<i64, Size1>;
template <size_t Size1, size_t Size2> using aa64 = array<a64<Size2>, Size1>;
template <class T> using hash_set = unordered_set<T>;
template <class T, class U> using hash_map = unordered_map<T, U>;

mt19937 gen(998244353);
const i64 inf = numeric_limits<i64>::max() / 2;

template <class T> inline i64 len(const T &a) { return (i64)(a.size()); }
inline void fast() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); }
template <class T, class S> inline bool check_min(T &a, S b) {
  if (a > b)
    return a = b, 1;
  return 0;
}
template <class T, class S> inline bool check_max(T &a, S b) {
  if (a < b)
    return a = b, 1;
  return 0;
}

void read() {}
template <class T, class... U> void read(T &a, U &...b) {
  cin >> a;
  read(b...);
}
void print() {}
template <class T, class... U> void print(const T &a, const U &...b) {
  cout << a << " ";
  print(b...);
}
void println() { cout << "\\n"; }
template <class T, class... U> void println(const T &a, const U &...b) {
  cout << a << " ";
  println(b...);
}

struct Problem {
  void files(str in, str out) {
#ifdef ONLINE_JUDGE
    freopen(in.c_str(), "r", stdin), freopen(out.c_str(), "w", stdout);
#endif
  }
  void solve(), input();
  void many() {
    i64 t;
    cin >> t;
    while (t--)
      input(), solve();
  }
  void make(bool mt = 0) {
    if (mt)
      many();
    else
      input(), solve();
  }
} problem;

signed main() {
  fast();
  problem.make();
#ifdef _DEBUG
  println();
  println("[finished]");
  system("pause > nul");
#endif
  return 0;
}

struct Object {
  p64 p;
  i64 dir;
  bool operator<(Object a) const {
    pair<p64, i64> p1 = {p, dir};
    pair<p64, i64> p2 = {a.p, a.dir};
    return p1 < p2;
  }
};

i64 n, m, k;
i64 x1, y1, x2, y2;
vv64 a;
vec<p64> dirs = {{-1, 0}, {+1, 0}, {0, -1}, {0, +1}};

i64 ok(i64 i, i64 j) {
  if (!(0 <= i && i < n && 0 <= j && j < m))
    return 0;
  return a[i][j];
}

i64 get_hash(Object v) { return v.dir * n * m + v.p.ft * m + v.p.sd; }

i64 dijkstra(p64 s, p64 t) {
  map<i64, i64> d;
  set<pair<i64, Object>> q;
  forn(z, 4) {
    i64 h = get_hash({s, z});
    d[h] = 0;
    q.insert({d[h], {s, z}});
  }
  while (!q.empty()) {
    Object v = q.begin()->sd;
    q.erase(q.begin());
    i64 h1 = get_hash(v);
    forn(j, 4) {
      Object u;
      u.p = {v.p.ft + dirs[j].ft, v.p.sd + dirs[j].sd};
      u.dir = j;
      if (!ok(u.p.ft, u.p.sd))
        continue;
      i64 h2 = get_hash(u);
      if (!d.count(h2))
        d[h2] = inf;
      i64 cur = inf;
      if (u.dir == v.dir) {
        cur = d[h1] + 1;
      } else {
        cur = d[h1] / k * k + k;
      }
      if (d[h2] > cur) {
        q.erase({d[h2], u});
        d[h2] = cur;
        q.insert({d[h2], u});
      }
    }
  }
  i64 ans = inf;
  forn(z, 4) {
    i64 h = get_hash({t, z});
    if (d.count(h)) {
      check_min(ans, d[h]);
    }
  }
  return ans;
}

void Problem::solve() {
  i64 res = dijkstra({x1, y1}, {x2, y2});
  i64 ans = (res + k - 1) / k;
  if (res == inf)
    ans = -1;
  println(ans);
}

void Problem::input() {
  read(n, m, k);
  read(x1, y1, x2, y2);
  --x1, --y1, --x2, --y2;
  a.resize(n, v64(m, 0));
  forn(i, n) {
    forn(j, m) {
      char c;
      read(c);
      a[i][j] = c != '@';
    }
  }
}