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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6 + 7;

set<int> rw[N];
set<int> cl[N];

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m, k;
  cin >> n >> m >> k;
  int x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;
  x1--, y1--, x2--, y2--;
  vector<vector<char>> c;
  vector<vector<int>> up, dw, lf, rg, d;
  c.resize(n);
  up.resize(n);
  dw.resize(n);
  lf.resize(n);
  rg.resize(n);
  d.resize(n);
  for (int i = 0; i < n; i++) {
    c[i].resize(m);
    up[i].resize(m);
    dw[i].resize(m);
    lf[i].resize(m);
    rg[i].resize(m);
    d[i].resize(m);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> c[i][j];
    }
  }
  for (int i = 0; i < n; i++) {
    int lst = -1;
    for (int j = 0; j < m; j++) {
      if (c[i][j] == '@') {
        lst = j;
      }
      lf[i][j] = lst;
    }
  }
  for (int i = 0; i < n; i++) {
    int lst = m;
    for (int j = m - 1; j >= 0; j--) {
      if (c[i][j] == '@') {
        lst = j;
      }
      rg[i][j] = lst;
    }
  }
  for (int j = 0; j < m; j++) {
    int lst = -1;
    for (int i = 0; i < n; i++) {
      if (c[i][j] == '@') {
        lst = i;
      }
      up[i][j] = lst;
    }
  }
  for (int j = 0; j < m; j++) {
    int lst = n;
    for (int i = n - 1; i >= 0; i--) {
      if (c[i][j] == '@') {
        lst = i;
      }
      dw[i][j] = lst;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      rw[i].insert(j);
      cl[j].insert(i);
    }
  }
  const int inf = 1e9 + 7;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      d[i][j] = inf;
    }
  }
  queue<pair<int, int>> q;
  d[x1][y1] = 0;
  q.push({x1, y1});
  rw[x1].erase(y1);
  cl[y1].erase(x1);
  int cnt = 0;
  while (!q.empty()) {
    cnt++;
    int x = q.front().first;
    int y = q.front().second;
    q.pop();
    // up
    {
      int lim = max(x - k, up[x][y] + 1);
      int cur = x;
      while (true) {
        if (cl[y].empty())
          break;
        auto to = cl[y].lower_bound(cur);
        if (to == cl[y].begin()) {
          break;
        }
        to--;
        if (*to < lim) {
          break;
        }
        d[*to][y] = d[x][y] + 1;
        cur = *to;
        q.push({*to, y});
        rw[*to].erase(y);
        cl[y].erase(to);
      }
    }
    // down
    {
      int lim = min(x + k, dw[x][y] - 1);
      int cur = x;
      while (true) {
        if (cl[y].empty())
          break;
        auto to = cl[y].lower_bound(cur);
        if (to == cl[y].end()) {
          break;
        }
        if (*to > lim) {
          break;
        }
        d[*to][y] = d[x][y] + 1;
        cur = *to;
        q.push({*to, y});
        rw[*to].erase(y);
        cl[y].erase(to);
      }
    }
    // left
    {
      int lim = max(y - k, lf[x][y] + 1);
      int cur = y;
      while (true) {
        if (rw[x].empty())
          break;
        auto to = rw[x].lower_bound(cur);
        if (to == rw[x].begin()) {
          break;
        }
        to--;
        if (*to < lim) {
          break;
        }
        d[x][*to] = d[x][y] + 1;
        cur = *to;
        q.push({x, *to});
        cl[*to].erase(x);
        rw[x].erase(to);
      }
    }
    // right
    {
      int lim = min(y + k, rg[x][y] - 1);
      int cur = y;
      while (true) {
        if (rw[x].empty())
          break;
        auto to = rw[x].lower_bound(cur);
        if (to == rw[x].end()) {
          break;
        }
        if (*to > lim) {
          break;
        }
        d[x][*to] = d[x][y] + 1;
        cur = *to;
        q.push({x, *to});
        cl[*to].erase(x);
        rw[x].erase(to);
      }
    }
  }
  cout << (d[x2][y2] == inf ? -1 : d[x2][y2]) << '\\n';
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e6 + 7;

set<int> rw[N];
set<int> cl[N];

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m, k;
  cin >> n >> m >> k;
  int x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;
  x1--, y1--, x2--, y2--;
  vector<vector<char>> c;
  vector<vector<int>> up, dw, lf, rg, d;
  c.resize(n);
  up.resize(n);
  dw.resize(n);
  lf.resize(n);
  rg.resize(n);
  d.resize(n);
  for (int i = 0; i < n; i++) {
    c[i].resize(m);
    up[i].resize(m);
    dw[i].resize(m);
    lf[i].resize(m);
    rg[i].resize(m);
    d[i].resize(m);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> c[i][j];
    }
  }
  for (int i = 0; i < n; i++) {
    int lst = -1;
    for (int j = 0; j < m; j++) {
      if (c[i][j] == '@') {
        lst = j;
      }
      lf[i][j] = lst;
    }
  }
  for (int i = 0; i < n; i++) {
    int lst = m;
    for (int j = m - 1; j >= 0; j--) {
      if (c[i][j] == '@') {
        lst = j;
      }
      rg[i][j] = lst;
    }
  }
  for (int j = 0; j < m; j++) {
    int lst = -1;
    for (int i = 0; i < n; i++) {
      if (c[i][j] == '@') {
        lst = i;
      }
      up[i][j] = lst;
    }
  }
  for (int j = 0; j < m; j++) {
    int lst = n;
    for (int i = n - 1; i >= 0; i--) {
      if (c[i][j] == '@') {
        lst = i;
      }
      dw[i][j] = lst;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      rw[i].insert(j);
      cl[j].insert(i);
    }
  }
  const int inf = 1e9 + 7;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      d[i][j] = inf;
    }
  }
  queue<pair<int, int>> q;
  d[x1][y1] = 0;
  q.push({x1, y1});
  rw[x1].erase(y1);
  cl[y1].erase(x1);
  int cnt = 0;
  while (!q.empty()) {
    cnt++;
    if (cnt > 1e6)
      assert(0);
    int x = q.front().first;
    int y = q.front().second;
    q.pop();
    // up
    {
      int lim = max(x - k, up[x][y] + 1);
      int cur = x;
      while (true) {
        if (cl[y].empty())
          break;
        auto to = lower_bound(cl[y].begin(), cl[y].end(), cur);
        if (to == cl[y].begin()) {
          break;
        }
        to--;
        if (*to < lim) {
          break;
        }
        d[*to][y] = d[x][y] + 1;
        cur = *to;
        q.push({*to, y});
        rw[*to].erase(y);
        cl[y].erase(*to);
      }
    }
    // down
    {
      int lim = min(x + k, dw[x][y] - 1);
      int cur = x;
      while (true) {
        if (cl[y].empty())
          break;
        auto to = upper_bound(cl[y].begin(), cl[y].end(), cur);
        if (to == cl[y].end()) {
          break;
        }
        if (*to > lim) {
          break;
        }
        d[*to][y] = d[x][y] + 1;
        cur = *to;
        q.push({*to, y});
        rw[*to].erase(y);
        cl[y].erase(*to);
      }
    }
    // left
    {
      int lim = max(y - k, lf[x][y] + 1);
      int cur = y;
      while (true) {
        if (rw[x].empty())
          break;
        auto to = lower_bound(rw[x].begin(), rw[x].end(), cur);
        if (to == rw[x].begin()) {
          break;
        }
        to--;
        if (*to < lim) {
          break;
        }
        d[x][*to] = d[x][y] + 1;
        cur = *to;
        q.push({x, *to});
        cl[*to].erase(x);
        rw[x].erase(*to);
      }
    }
    // right
    {
      int lim = min(y + k, rg[x][y] - 1);
      int cur = y;
      while (true) {
        if (rw[x].empty())
          break;
        auto to = upper_bound(rw[x].begin(), rw[x].end(), cur);
        if (to == rw[x].end()) {
          break;
        }
        if (*to > lim) {
          break;
        }
        d[x][*to] = d[x][y] + 1;
        cur = *to;
        q.push({x, *to});
        cl[*to].erase(x);
        rw[x].erase(*to);
      }
    }
  }
  cout << (d[x2][y2] == inf ? -1 : d[x2][y2]) << '\\n';
  return 0;
}