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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iosfwd>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;

long long t, n, m, u, v, q, k, p;
const int N = 1e6 + 500;
const long long mod = 1e9 + 7;
const long long INF = 1LL << 57;

long long arr[N];
vector<long long> dist[N];
vector<int> blocked[N];
set<int> row[N], col[N], revRow[N], revCol[N];
int xa, ya, xb, yb;
string str;

queue<pair<int, int>> Q;

int bfs(int srcX, int srcY, int distX, int distY) {
  dist[srcX][srcY] = 0;
  Q.push(make_pair(srcX, srcY));
  col[srcY].erase(srcX);
  row[srcX].erase(srcY);
  revCol[srcY].erase(-srcX);
  revRow[srcX].erase(-srcY);

  while (!Q.empty()) {
    pair<int, int> node = Q.front();
    if (node.first == distX and node.second == distY)
      break;
    Q.pop();
    vector<pair<int, int>> toErase;
    auto it = revRow[node.first].upper_bound(-node.second);
    while (it != revRow[node.first].end()) {
      int x = abs((*it));
      if (x < node.second - k or blocked[node.first][x])
        break;
      else {
        dist[node.first][x] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(node.first, (x)));
        Q.push(make_pair(node.first, (x)));
      }
      ++it;
    }
    auto it2 = row[node.first].upper_bound(node.second);
    while (it2 != row[node.first].end()) {
      if ((*it2) > node.second + k or blocked[node.first][*it2])
        break;
      else {
        dist[node.first][*it2] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(node.first, (*it2)));
        Q.push(make_pair(node.first, (*it2)));
      }
      ++it2;
    }
    auto it3 = col[node.second].upper_bound(node.first);
    while (it3 != col[node.second].end()) {
      if ((*it3) > node.first + k or blocked[*it3][node.second])
        break;
      else {
        dist[*it3][node.second] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair((*it3), node.second));
        Q.push(make_pair((*it3), node.second));
      }
      ++it3;
    }
    auto it4 = revCol[node.second].upper_bound(-node.first);
    while (it4 != revCol[node.second].end()) {
      int x = abs((*it4));
      if (x < node.first - k or blocked[x][node.second])
        break;
      else {
        dist[x][node.second] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(x, node.second));
        Q.push(make_pair(x, node.second));
      }
      ++it4;
    }
    for (auto it : toErase) {
      col[it.second].erase(it.first);
      row[it.first].erase(it.second);
      revRow[it.first].erase(-it.second);
      revCol[it.second].erase(-it.first);
    }
  }

  if (dist[distX][distY] == INF)
    return -1;
  else
    return dist[distX][distY];
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> k;
  cin >> xa >> ya >> xb >> yb;

  for (int i = 1; i <= n; ++i) {
    dist[i].resize(m + 1);
    blocked[i].resize(m + 1);
    for (int j = 1; j <= m; ++j)
      dist[i][j] = INF;
    for (int j = 1; j <= m; ++j) {
      row[i].insert(j);
      revRow[i].insert(-j);
    }
  }

  for (int j = 1; j <= m; ++j)
    for (int i = 1; i <= n; ++i) {
      col[j].insert(i);
      revCol[j].insert(-i);
    }

  for (int i = 1; i <= n; ++i) {
    cin >> str;
    for (int j = 0; j < str.size(); ++j) {
      if (str[j] == '@') {
        blocked[i][j + 1] = true;
      }
    }
  }
  cout << bfs(xa, ya, xb, yb) << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iosfwd>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;

long long t, n, m, u, v, q, k, p;
const int N = 1e6 + 500;
const long long mod = 1e9 + 7;
const long long INF = 1LL << 57;

long long arr[N];
vector<long long> dist[N];
vector<int> blocked[N];
set<int> row[N], col[N], revRow[N], revCol[N];
int xa, ya, xb, yb;
string str;

queue<pair<int, int>> Q;

int bfs(int srcX, int srcY, int distX, int distY) {
  dist[srcX][srcY] = 0;
  Q.push(make_pair(srcX, srcY));
  col[srcY].erase(srcX);
  row[srcX].erase(srcY);
  revCol[srcY].erase(-srcX);
  revRow[srcX].erase(-srcY);

  while (!Q.empty()) {
    pair<int, int> node = Q.front();
    if (node.first == distX and node.second == distY)
      break;
    Q.pop();
    vector<pair<int, int>> toErase;
    auto it = upper_bound(revRow[node.first].begin(), revRow[node.first].end(),
                          -node.second);
    while (it != revRow[node.first].end()) {
      int x = abs((*it));
      if (x < node.second - k or blocked[node.first][x])
        break;
      else {
        dist[node.first][x] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(node.first, (x)));
        Q.push(make_pair(node.first, (x)));
      }
      ++it;
    }
    auto it2 = upper_bound(row[node.first].begin(), row[node.first].end(),
                           node.second);
    while (it2 != row[node.first].end()) {
      if ((*it2) > node.second + k or blocked[node.first][*it2])
        break;
      else {
        dist[node.first][*it2] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(node.first, (*it2)));
        Q.push(make_pair(node.first, (*it2)));
      }
      ++it2;
    }
    auto it3 = upper_bound(col[node.second].begin(), col[node.second].end(),
                           node.first);
    while (it3 != col[node.second].end()) {
      if ((*it3) > node.first + k or blocked[*it3][node.second])
        break;
      else {
        dist[*it3][node.second] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair((*it3), node.second));
        Q.push(make_pair((*it3), node.second));
      }
      ++it3;
    }
    auto it4 = upper_bound(revCol[node.second].begin(),
                           revCol[node.second].end(), -node.first);
    while (it4 != revCol[node.second].end()) {
      int x = abs((*it4));
      if (x < node.first - k or blocked[x][node.second])
        break;
      else {
        dist[x][node.second] = dist[node.first][node.second] + 1;
        toErase.push_back(make_pair(x, node.second));
        Q.push(make_pair(x, node.second));
      }
      ++it4;
    }
    for (auto it : toErase) {
      col[it.second].erase(it.first);
      row[it.first].erase(it.second);
      revRow[it.first].erase(-it.second);
      revCol[it.second].erase(-it.first);
    }
  }

  if (dist[distX][distY] == INF)
    return -1;
  else
    return dist[distX][distY];
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> k;
  cin >> xa >> ya >> xb >> yb;

  for (int i = 1; i <= n; ++i) {
    dist[i].resize(m + 1);
    blocked[i].resize(m + 1);
    for (int j = 1; j <= m; ++j)
      dist[i][j] = INF;
    for (int j = 1; j <= m; ++j) {
      row[i].insert(j);
      revRow[i].insert(-j);
    }
  }

  for (int j = 1; j <= m; ++j)
    for (int i = 1; i <= n; ++i) {
      col[j].insert(i);
      revCol[j].insert(-i);
    }

  for (int i = 1; i <= n; ++i) {
    cin >> str;
    for (int j = 0; j < str.size(); ++j) {
      if (str[j] == '@') {
        blocked[i][j + 1] = true;
      }
    }
  }
  cout << bfs(xa, ya, xb, yb) << endl;
}