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

#include <bits/stdc++.h>

#define REP(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

using pii = pair<int, int>;
using tri = tuple<int, int, int>;

int main() {

  cin.tie(0);
  ios::sync_with_stdio(false);

  constexpr int INF = INT_MAX;

  int H, W, K, x1, y1, x2, y2;
  cin >> H >> W >> K >> x1 >> y1 >> x2 >> y2;
  --x1;
  --y1;
  --x2;
  --y2;
  vector<string> c(H);
  REP(i, H) cin >> c[i];

  vector<set<int>> s_h(H), s_v(W);
  REP(i, H) REP(j, W) {
    if (c[i][j] == '.') {
      s_h[i].insert(j);
      s_v[j].insert(i);
    }
  }

  vector<vector<int>> at_h(H, vector<int>(W + 1, 0)),
      at_v(W, vector<int>(H + 1, 0));
  REP(i, H) REP(j, W) { at_h[i][j + 1] = at_h[i][j] + (c[i][j] == '@'); }
  REP(j, W) REP(i, H) { at_v[j][i + 1] = at_v[j][i] + (c[i][j] == '@'); }

  vector<vector<int>> dp(H, vector<int>(W, INF));
  queue<pii> q;

  function<void(int, int, int)> update = [&](int x, int y, int d) {
    dp[x][y] = d;
    q.emplace(x, y);
    s_h[x].erase(y);
    s_v[y].erase(x);
  };

  update(x1, y1, 0);

  while (!q.empty()) {

    auto [x0, y0] = q.front();
    q.pop();
    int dn = dp[x0][y0] + 1;
    int x, y;

    // left
    x = x0;
    y = y0;
    while (true) {
      auto it = s_h[x].lower_bound(y);
      if (it == s_h[x].begin())
        break;
      --it;
      y = *it;
      if (abs(y0 - y) > K || at_h[x][y0] != at_h[x][y])
        break;
      update(x, y, dn);
    }

    // right
    x = x0;
    y = y0;
    while (true) {
      auto it = s_h[x].upper_bound(y);
      if (it == s_h[x].end())
        break;
      y = *it;
      if (abs(y0 - y) > K || at_h[x][y0] != at_h[x][y])
        break;
      update(x, y, dn);
    }

    // up
    x = x0;
    y = y0;
    while (true) {
      auto it = s_v[y].lower_bound(x);
      if (it == s_v[y].begin())
        break;
      --it;
      x = *it;
      if (abs(x0 - x) > K || at_v[y][x0] != at_v[y][x])
        break;
      update(x, y, dn);
    }

    // right
    x = x0;
    y = y0;
    while (true) {
      auto it = s_v[y].upper_bound(x);
      if (it == s_v[y].end())
        break;
      x = *it;
      if (abs(x0 - x) > K || at_v[y][x0] != at_v[y][x])
        break;
      update(x, y, dn);
    }
  }

  if (dp[x2][y2] == INF) {
    cout << (-1) << endl;
  } else {
    cout << dp[x2][y2] << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

using pii = pair<int, int>;
using tri = tuple<int, int, int>;

int main() {

  cin.tie(0);
  ios::sync_with_stdio(false);

  int H, W, K, x1, y1, x2, y2;
  cin >> H >> W >> K >> x1 >> y1 >> x2 >> y2;
  --x1;
  --y1;
  --x2;
  --y2;
  vector<string> c(H);
  REP(i, H) cin >> c[i];

  vector<list<int>> l_h(H, list<int>(W)), l_v(W, list<int>(H));
  vector<vector<list<int>::iterator>> it_h(H, vector<list<int>::iterator>(W)),
      it_v(H, vector<list<int>::iterator>(W));
  REP(i, H) {
    auto it = l_h[i].begin();
    REP(j, W) {
      *it = j;
      it_h[i][j] = it;
      ++it;
    }
  }
  REP(j, W) {
    auto it = l_v[j].begin();
    REP(i, H) {
      *it = i;
      it_v[i][j] = it;
      ++it;
    }
  }

  vector<vector<int>> dp(H, vector<int>(W, INT_MAX));
  priority_queue<tri, vector<tri>, greater<tri>> q;
  dp[x1][y1] = 0;
  q.emplace(dp[x1][y1], x1, y1);
  while (!q.empty()) {
    auto [d, x0, y0] = q.top();
    q.pop();

    if (d > dp[x0][y0])
      continue;

    int dn = d + 1;

    int x, y, xn, yn;

    // left
    x = x0;
    y = y0;
    xn = x0;
    while (true) {
      if (it_h[x][y] == l_h[x].begin())
        break;
      yn = *prev(it_h[x][y]);
      if (c[xn][yn] == '@' || abs(y0 - yn) > K)
        break;
      if (dp[xn][yn] > dn) {
        dp[xn][yn] = dn;
        q.emplace(dp[xn][yn], xn, yn);
      }
      y = yn;
    }

    // right
    x = x0;
    y = y0;
    xn = x0;
    while (true) {
      if (next(it_h[x][y]) == l_h[x].end())
        break;
      yn = *next(it_h[x][y]);
      if (c[xn][yn] == '@' || abs(y0 - yn) > K)
        break;
      if (dp[xn][yn] > dn) {
        dp[xn][yn] = dn;
        q.emplace(dp[xn][yn], xn, yn);
      }
      y = yn;
    }

    // up
    x = x0;
    y = y0;
    yn = y0;
    while (true) {
      if (it_v[x][y] == l_v[y].begin())
        break;
      xn = *prev(it_v[x][y]);
      if (c[xn][yn] == '@' || abs(x0 - xn) > K)
        break;
      if (dp[xn][yn] > dn) {
        dp[xn][yn] = dn;
        q.emplace(dp[xn][yn], xn, yn);
      }
      x = xn;
    }

    // down
    x = x0;
    y = y0;
    yn = y0;
    while (true) {
      if (next(it_v[x][y]) == l_v[y].end())
        break;
      xn = *next(it_v[x][y]);
      if (c[xn][yn] == '@' || abs(x0 - xn) > K)
        break;
      if (dp[xn][yn] > dn) {
        dp[xn][yn] = dn;
        q.emplace(dp[xn][yn], xn, yn);
      }
      x = xn;
    }

    l_h[x0].erase(it_h[x0][y0]);
    l_v[y0].erase(it_v[x0][y0]);
  }

  /*
  REP(i, H) {
      REP(j, W) {
          if (dp[i][j] == INT_MAX) {
              cout << "---";
          } else {
              cout << setw(3) << dp[i][j];
          }
      }
      cout << endl;
  }
  */

  if (dp[x2][y2] == INT_MAX) {
    cout << (-1) << endl;
  } else {
    cout << dp[x2][y2] << endl;
  }

  return 0;
}