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

#include <algorithm>
#include <array>
#include <cassert>
#include <chrono>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <ostream>
#include <random>
#include <set>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef ONLINE_JUDGE
#pragma GCC optimize("O2")
#pragma GCC target("avx,avx2")
#endif

using namespace std;

using u64 = uint64_t;
using i64 = int64_t;
using u32 = uint32_t;
using vi = vector<int>;
using vi64 = vector<i64>;

#define seq(i, a, b) for (int i = (a); i < (b); ++i)
#define rev(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define sz(x) ((int)x.size())
#define all(x) x.begin(), x.end()
#define dbg(x)                                                                 \\
  { cerr << #x << ": " << x << endl; }

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n;
  cin >> n;

  vector<char> occ(n * n, true);
  vector<int> cost(n * n, false);

  auto outside = [&](int x, int y) {
    return !(0 <= x && x < n && 0 <= y && y < n);
  };

  auto at = [&](int x, int y) -> auto & {
    static char unocc = false;
    if (outside(x, y))
      return unocc;
    return occ[x + y * n];
  };

  auto cost_at = [&](int x, int y) -> auto & { return cost[x + y * n]; };

  seq(i, 0, n * n) {
    int x = i % n;
    int y = i / n;
    cost_at(x, y) = min({x, y, n - x - 1, n - y - 1});
  }

  vi A(n * n);
  for (auto &x : A)
    cin >> x;
  int res = 0;
  for (auto i : A) {
    --i;

    // seq(y,0,n) {
    //   seq(x,0,n) {
    //     cout << cost_at(x,y) << " ";
    //   }
    //   cout << "\\n";
    // }
    // cout << "\\n";
    int c = cost_at(i % n, i / n);
    res += c;

    // Update
    deque<tuple<int, int, int>> Q;
    Q.push_front({i % n, i / n, c});
    at(i % n, i / n) = false;
    while (!Q.empty()) {
      auto [x, y, cost] = Q.back();
      // cout << x << ", " << y << ", " << cost << endl;
      Q.pop_back();

      int nc = cost + at(x, y);
      auto f = [&nc, &Q, &cost_at, &outside](int nx, int ny) {
        if (!outside(nx, ny) && cost_at(nx, ny) > nc) {
          cost_at(nx, ny) = nc;
          Q.push_front({nx, ny, nc});
        }
      };

      f(x + 1, y);
      f(x - 1, y);
      f(x, y + 1);
      f(x, y - 1);
    }
  }
  cout << res << "\\n";
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <memory>
#include <numeric>

#include <array>
#include <deque>
#include <map>
#include <set>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <chrono>
#include <cstring>
#include <ostream>
#include <random>
#include <type_traits>
#include <utility>

#ifdef ONLINE_JUDGE
#pragma GCC optimize("O2")
#pragma GCC target("avx,avx2")
#endif

using namespace std;

using u64 = uint64_t;
using i64 = int64_t;
using u32 = uint32_t;
using vi = vector<int>;
using vi64 = vector<i64>;

#define seq(i, a, b) for (int i = (a); i < (b); ++i)
#define rev(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define sz(x) ((int)x.size())
#define all(x) x.begin(), x.end()
#define dbg(x)                                                                 \\
  { cerr << #x << ": " << x << endl; }

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n;
  cin >> n;

  vector<char> occ(n * n, true);

  auto outside = [&](int x, int y) {
    return !(0 <= x && x < n && 0 <= y && y < n);
  };

  auto at = [&](int x, int y) -> auto & {
    static char unocc = false;
    if (outside(x, y))
      return unocc;
    return occ[x + y * n];
  };

  vi A(n * n);
  for (auto &x : A)
    cin >> x;
  int res = 0;
  for (auto i : A) {
    int count = -1;
    --i;
    at(i % n, i / n) = false;
    vector<char> vis(n * n, 0);
    deque<tuple<int, int, int>> Q;
    Q.push_front({i % n, i / n, 0});
    while (!Q.empty()) {
      auto [x, y, d] = Q.back();
      Q.pop_back();
      if (outside(x, y)) {
        count = d;
        break;
      }

      if (vis[x + y * n])
        continue;
      vis[x + y * n] = true;

      if (at(x + 1, y))
        Q.push_front({x + 1, y, d + 1});
      else
        Q.push_back({x + 1, y, d});
      if (at(x - 1, y))
        Q.push_front({x - 1, y, d + 1});
      else
        Q.push_back({x - 1, y, d});
      if (at(x, y + 1))
        Q.push_front({x, y + 1, d + 1});
      else
        Q.push_back({x, y + 1, d});
      if (at(x, y - 1))
        Q.push_front({x, y - 1, d + 1});
      else
        Q.push_back({x, y - 1, d});
    }
    assert(count != -1);
    res += count;
  }
  cout << res << "\\n";
}