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

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

typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef pair<ll, ll> pll;
typedef vector<bool> vb;
const ll oo = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
#define sz(c) ll((c).size())
#define all(c) begin(c), end(c)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORD(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define xx first
#define yy second
#define TR(X)                                                                  \\
  ({                                                                           \\
    if (1)                                                                     \\
      cerr << "TR: " << (#X) << " = " << (X) << endl;                          \\
  })

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  ll m, n, k;
  cin >> m >> n >> k;

  ll si, sj, ti, tj;
  cin >> si >> sj >> ti >> tj;
  si--, sj--, ti--, tj--;

  vector<string> a(m);
  FOR(i, 0, m) cin >> a[i];

  auto wall = [&](ll i, ll j) {
    return i < 0 || i >= m || j < 0 || j >= n || a[i][j] == '@';
  };
  assert(!wall(si, sj));
  assert(!wall(ti, tj));

  vvl dist(m, vl(n, oo));
  vector<set<ll>> row(m), col(n);
  FOR(i, 0, m) FOR(j, 0, n) {
    row[i].insert(j);
    col[j].insert(i);
  }

  queue<pll> q;

  auto update = [&](ll i, ll j, ll d) {
    if (wall(i, j) || d >= dist[i][j])
      return;
    q.push({i, j});
    dist[i][j] = d;
  };

  update(si, sj, 0);

  while (sz(q)) {
    ll i, j;
    tie(i, j) = q.front();
    q.pop();

    auto valid = [&](ll ni, ll nj) {
      return !wall(ni, nj) && abs(i - ni) + abs(j - nj) <= k;
    };
    {
      auto lo = col[j].lower_bound(i);
      while (lo != begin(col[j]) && valid(*prev(lo), j))
        --lo;

      auto hi = col[j].upper_bound(i);
      while (hi != end(col[j]) && valid(*hi, j))
        ++hi;

      for (auto it = lo; it != hi; it++)
        update(*it, j, dist[i][j] + 1);
      col[j].erase(lo, hi);
    }
    {
      auto lo = row[i].lower_bound(j);
      while (lo != begin(row[i]) && valid(i, *prev(lo)))
        --lo;

      auto hi = row[i].upper_bound(j);
      while (hi != end(row[i]) && valid(i, *hi))
        ++hi;

      for (auto it = lo; it != hi; it++)
        update(i, *it, dist[i][j] + 1);
      row[i].erase(lo, hi);
    }
  }

  ll res = dist[ti][tj];
  if (res == oo)
    res = -1;
  cout << res << endl;
}


Error: TLE

Fixed submission:

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

typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef pair<ll, ll> pll;
typedef vector<bool> vb;
const ll oo = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
#define sz(c) ll((c).size())
#define all(c) begin(c), end(c)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORD(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define xx first
#define yy second
#define TR(X)                                                                  \\
  ({                                                                           \\
    if (1)                                                                     \\
      cerr << "TR: " << (#X) << " = " << (X) << endl;                          \\
  })

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  ll m, n, k;
  cin >> m >> n >> k;

  ll si, sj, ti, tj;
  cin >> si >> sj >> ti >> tj;
  si--, sj--, ti--, tj--;

  vector<string> a(m);
  FOR(i, 0, m) cin >> a[i];

  auto wall = [&](ll i, ll j) {
    return i < 0 || i >= m || j < 0 || j >= n || a[i][j] == '@';
  };
  assert(!wall(si, sj));
  assert(!wall(ti, tj));

  vvl dist(m, vl(n, oo));
  vvl goL(m, vl(n)), goR(m, vl(n)), goU(m, vl(n)), goD(m, vl(n));
  FOR(i, 0, m) FOR(j, 0, n) {
    goU[i][j] = i - 1, goD[i][j] = i + 1;
    goL[i][j] = j - 1, goR[i][j] = j + 1;
  }

  queue<pll> q;

  auto update = [&](ll i, ll j, ll d) {
    if (wall(i, j) || d >= dist[i][j])
      return;
    q.push({i, j});
    dist[i][j] = d;
    //		cerr << i << " " << j << " " << d << endl;

    ll pi = goU[i][j], ni = goD[i][j];
    if (!wall(pi, j))
      goD[pi][j] = ni;
    if (!wall(ni, j))
      goU[ni][j] = pi;

    ll pj = goL[i][j], nj = goR[i][j];
    if (!wall(i, pj))
      goR[i][pj] = nj;
    if (!wall(i, nj))
      goL[i][nj] = pj;
  };

  update(si, sj, 0);

  while (sz(q)) {
    ll i, j;
    tie(i, j) = q.front();
    q.pop();

    auto valid = [&](ll ni, ll nj) {
      return !wall(ni, nj) && abs(i - ni) + abs(j - nj) <= k;
    };

    for (ll ni = goU[i][j]; valid(ni, j); ni = goU[ni][j])
      update(ni, j, dist[i][j] + 1);
    for (ll ni = goD[i][j]; valid(ni, j); ni = goD[ni][j])
      update(ni, j, dist[i][j] + 1);
    for (ll nj = goL[i][j]; valid(i, nj); nj = goL[i][nj])
      update(i, nj, dist[i][j] + 1);
    for (ll nj = goR[i][j]; valid(i, nj); nj = goR[i][nj])
      update(i, nj, dist[i][j] + 1);
  }

  ll res = dist[ti][tj];
  if (res == oo)
    res = -1;
  cout << res << endl;
}