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

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

#define lli long long int
#define REP(i, s, n) for (lli i = s; i < n; i++)
#define NUM 2520
#define INF (1LL << 50)
#define DEBUG 0
#define mp(a, b) make_pair(a, b)
#define SORT(V) sort(V.begin(), V.end())
#define PI (3.141592653589794)
#define TO_STRING(VariableName) #VariableName
#define LOG(x)                                                                 \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(x) << "=" << x << " " << endl;
#define LOG2(x, y)                                                             \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(x) << "=" << x << " " << TO_STRING(y) << "=" << y << endl;
#define LOG3(x, y, z)                                                          \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(x) << "=" << x << " " << TO_STRING(y) << "=" << y << " " \\
         << TO_STRING(z) << "=" << z << endl;
#define LOG4(w, x, y, z)                                                       \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(w) << "=" << w << " " << TO_STRING(x) << "=" << x << " " \\
         << TO_STRING(y) << "=" << y << " " << TO_STRING(z) << "=" << z        \\
         << endl;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

lli dist[600][600];
lli has[600][600];

int main() {

  lli N;
  cin >> N;

  REP(i, 1, N + 1) {
    REP(j, 1, N + 1) {
      has[i][j] = 1;
      dist[i][j] = min({i, j, N + 1LL - i, N + 1LL - j}) - 1;
    }
  }

  lli _ = N * N;
  lli ans = 0;
  while (_--) {
    lli a;
    cin >> a;
    lli nowI = (a - 1) / N + 1;
    lli nowJ = (a - 1) % N + 1;
    ans += dist[nowI][nowJ];

    lli di[4] = {-1, 0, 1, 0};
    lli dj[4] = {0, 1, 0, -1};

    queue<pair<lli, lli>> q;
    queue<lli> qd;
    has[nowI][nowJ] = 0;

    q.push({nowI, nowJ});
    qd.push(0);

    while (q.size()) {
      pair<lli, lli> topP = q.front();
      lli nowD = qd.front();
      q.pop();
      qd.pop();

      REP(k, 0, 4) {
        pair<lli, lli> nexP = topP;
        nexP.first += di[k];
        nexP.second += dj[k];
        if (dist[nowI][nowJ] + nowD < dist[nexP.first][nexP.second]) {
          dist[nexP.first][nexP.second] = dist[nowI][nowJ] + nowD;
          q.push(nexP);
          qd.push(nowD + has[nexP.first][nexP.second]);
        }
      }
    }
  }

  cout << ans << endl;

  // Failed to predict input format
  return 0;
}


Error: TLE

Fixed submission:

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

#define lli long long int
#define REP(i, s, n) for (int i = s; i < n; i++)
#define NUM 2520
#define INF (1LL << 50)
#define DEBUG 0
#define mp(a, b) make_pair(a, b)
#define SORT(V) sort(V.begin(), V.end())
#define PI (3.141592653589794)
#define TO_STRING(VariableName) #VariableName
#define LOG(x)                                                                 \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(x) << "=" << x << " " << endl;
#define LOG2(x, y)                                                             \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(x) << "=" << x << " " << TO_STRING(y) << "=" << y << endl;
#define LOG3(x, y, z)                                                          \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(x) << "=" << x << " " << TO_STRING(y) << "=" << y << " " \\
         << TO_STRING(z) << "=" << z << endl;
#define LOG4(w, x, y, z)                                                       \\
  if (DEBUG)                                                                   \\
    cout << TO_STRING(w) << "=" << w << " " << TO_STRING(x) << "=" << x << " " \\
         << TO_STRING(y) << "=" << y << " " << TO_STRING(z) << "=" << z        \\
         << endl;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

lli dd[600][600];

typedef struct UnionFind {
  vector<lli> par; // par[i]:iの親番号 par[3] = 2 : 3の親が2
  vector<lli>
      size; // size[i]:iの大きさ 自分のみのときは1,根っこにsizeを持たせる*/

  UnionFind(int N) { /*最初はすべてが根であると初期化*/
    REP(i, 0, N) {
      par.push_back(i);
      size.push_back(1);
    }
  }

  lli root(lli x) { /*データxが属する木の根を再起で得る root(x) = {xの木の根}}*/
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(lli x, lli y) { /*xとyの併合*/
    lli rx = root(x);
    lli ry = root(y);
    if (rx == ry)
      return;
    par[rx] = ry; /*xとyの根が同じじゃない: xの根をrxをyの根ryに変更する */
    lli resize = size[rx] + size[ry];
    size[rx] = resize;
    size[ry] = resize;
  }

  bool same(lli x, lli y) {
    lli rx = root(x);
    lli ry = root(y);
    return rx == ry;
  }

  lli getSize(lli x) {
    lli rx = root(x);
    return size[rx];
  }
};

int main() {

  lli n;
  cin >> n;

  REP(i, 0, 600) REP(j, 0, 600) {
    dd[i][j] = 1;
    if (i == 0 || i == n + 1 || j == 0 || j == n + 1)
      dd[i][j] = 0;
  }

  lli ans = 0;
  REP(_, 0, n * n) {
    lli a;
    cin >> a;
    lli nowY = (a - 1) / n + 1;
    lli nowX = (a - 1) % n + 1;

    priority_queue<pair<lli, pair<lli, lli>>, vector<pair<lli, pair<lli, lli>>>,
                   greater<pair<lli, pair<lli, lli>>>>
        q;
    q.push({dd[nowY][nowX], {nowX, nowY}});
    set<pair<lli, lli>> s;

    lli dx[4] = {-1, 0, 1, 0};
    lli dy[4] = {0, 1, 0, -1};

    while (q.size()) {
      pair<lli, lli> now = q.top().second;
      lli nowD = q.top().first;
      lli nowX = now.first;
      lli nowY = now.second;
      q.pop();
      s.insert({nowX, nowY});
      if (nowX <= -1 || nowX >= n + 2 || nowY <= -1 || nowY >= n + 2)
        continue;
      if (nowD > n)
        continue;

      if (nowX == 0 || nowX == n + 1 || nowY == 0 || nowY == n + 1) {
        LOG4(a, nowY, nowX, nowD);
        ans += (nowD - 1);
        break;
      }
      REP(k, 0, 4) {
        lli nx = nowX + dx[k];
        lli ny = nowY + dy[k];
        if (s.find({nx, ny}) != s.end())
          continue;
        q.push({nowD + dd[ny][nx], {nx, ny}});
      }
    }
    dd[nowY][nowX] = 0;
  }
  cout << ans << endl;

  return 0;
}