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

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

int dat[501][501] = {};
int dat2[501][501] = {};
bool block[501][501] = {};

struct S {
  int x;
  int y;
  int v;
};

auto cmp = [](const S &lhs, const S &rhs) { return lhs.v > rhs.v; };

void add(int x, int y, int v, int n, int m, queue<S> &s) {
  if (x == -1 || x == n || y == -1 || y == n)
    return;

  if (v < dat[x][y]) {
    dat[x][y] = v;
    int nv = v;
    if (!block[x][y])
      nv++;
    s.push({x, y, nv});
  }
}

void update(int x, int y, int v, int n, int m) {
  queue<S> search;

  search.push({x, y, v});
  while (!search.empty()) {
    S s = search.front();
    search.pop();

    int cv = s.v;

    add(s.x - 1, s.y, cv, n, m, search);
    add(s.x + 1, s.y, cv, n, m, search);
    add(s.x, s.y - 1, cv, n, m, search);
    add(s.x, s.y + 1, cv, n, m, search);
    // cout << search.size() << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;

  FOR_LT(i, 0, n) {
    FOR_LT(j, 0, n) {
      int a = i;
      int b = n - i - 1;
      int c = j;
      int d = n - j - 1;
      dat[i][j] = min(min(a, b), min(c, d));
    }
  }

  int64_t ans = 0;
  REP(n * n) {
    int m;
    cin >> m;
    m--;
    int x = m % n;
    int y = m / n;
    int v = dat[x][y];
    block[x][y] = true;
    update(x, y, v, n, m + 1);
    ans += v;
#if 0
        cout << x << "  " << y << " " << v << " " << ans << endl;
        FOR_LT(i, 0, n) {
            FOR_LT(j, 0, n) {
                cout << dat[i][j] << " ";
            }
            cout << endl;
        }
        cout << "map" << endl;
        FOR_LT(i, 0, n) {
            FOR_LT(j, 0, n) {
                cout << block[i][j] << " ";
            }
            cout << endl;
        }
#endif
  }

  cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

int dat[501][501] = {};
int dat2[501][501] = {};
bool block[501][501] = {};

struct S {
  int x;
  int y;
  int v;
};

auto cmp = [](const S &lhs, const S &rhs) { return lhs.v > rhs.v; };

void enqueue(int x, int y, int v, int n, int m,
             priority_queue<S, vector<S>, decltype(cmp)> &s) {
  if (x == -1 || x == n || y == -1 || y == n)
    return;
  if (dat2[x][y] == m)
    return;
  if (dat[x][y] <= v)
    return;
  s.push({x, y, v});
}

void update(int x, int y, int v, int n, int m) {
  priority_queue<S, vector<S>, decltype(cmp)> search(cmp);

  search.push({x, y, v});
  while (!search.empty()) {
    S s = search.top();
    search.pop();

    dat2[s.x][s.y] = m;

    int cv = s.v;

    if (s.x == x && s.y == y) {
    } else {
      dat[s.x][s.y] = min(dat[s.x][s.y], cv);
    }
    if (!block[s.x][s.y])
      cv++;
    // cout << "ss : " << search.size() << endl;

    enqueue(s.x - 1, s.y, cv, n, m, search);
    enqueue(s.x + 1, s.y, cv, n, m, search);
    enqueue(s.x, s.y - 1, cv, n, m, search);
    enqueue(s.x, s.y + 1, cv, n, m, search);
    // cout << search.size() << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;

  FOR_LT(i, 0, n) {
    FOR_LT(j, 0, n) {
      int a = i;
      int b = n - i - 1;
      int c = j;
      int d = n - j - 1;
      dat[i][j] = min(min(a, b), min(c, d));
    }
  }

  int64_t ans = 0;
  REP(n * n) {
    int m;
    cin >> m;
    m--;
    int x = m % n;
    int y = m / n;
    int v = dat[x][y];
    block[x][y] = true;
    update(x, y, v, n, m + 1);
    ans += v;
#if 0
		cout << x << "  " << y << " " << v << " " << ans << endl;
		FOR_LT(i, 0, n) {
			FOR_LT(j, 0, n) {
				cout << dat[i][j] << " ";
			}
			cout << endl;
		}
		cout << "map" << endl;
		FOR_LT(i, 0, n) {
			FOR_LT(j, 0, n) {
				cout << block[i][j] << " ";
			}
			cout << endl;
		}
#endif
  }

  cout << ans << endl;

  return 0;
}