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

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

int dp[2][nn][nn];
int sig[nn][nn];
void upd(int &x, int y) { x = max(x, y); }
int n;
int fst[nn][nn];
int ans = 0;
int ax[] = {-1, 1, 0, 0, 0}, ay[] = {0, 0, -1, 1, 0};

#define pii pair<int, int>
#define mp make_pair
vector<pii> wait[nn * nn];
int vis[nn][nn];
void spread(int now, int cg) {
  int eg = cg;
  vector<int> all;
  for (int i = 1 + cg - 1; i <= 1 + n - cg; i++)
    for (int j = 1 + cg - 1; j <= 1 + n - cg; j++)
      if (i and j and i <= n and j <= n)
        vis[i][j] = 0, wait[dp[now][i][j]].push_back(mp(i, j)),
        all.push_back(dp[now][i][j]), all.push_back(sig[i][j]);

  if (all.size() <= n * 10) {
    sort(all.begin(), all.end());
    reverse(all.begin(), all.end());
    for (int ii = 0; ii < all.size(); ii++)
      if (wait[all[ii]].size()) {
        int i = all[ii];
        for (int e = 0; e < wait[i].size(); e++) {
          pii p = wait[i][e];
          int x = p.first, y = p.second;
          if (vis[x][y])
            continue;
          vis[x][y] = 1;
          for (int k = 0; k < 4; k++) {
            if (x + ax[k] >= 1 + cg and x + ax[k] <= n - cg and
                y + ay[k] >= 1 + cg and y + ay[k] <= n - cg)
              if (dp[now][x + ax[k]][y + ay[k]] <
                  min(dp[now][x][y], sig[x + ax[k]][y + ay[k]])) {

                dp[now][x + ax[k]][y + ay[k]] =
                    min(dp[now][x][y], sig[x + ax[k]][y + ay[k]]);
                wait[dp[now][x + ax[k]][y + ay[k]]].push_back(
                    mp(x + ax[k], y + ay[k]));
              }
          }
        }
        wait[i].clear();
      }

  } else
    for (int i = n * n; i >= 1; i--)
      if (wait[i].size()) {
        for (int e = 0; e < wait[i].size(); e++) {
          pii p = wait[i][e];
          int x = p.first, y = p.second;
          if (vis[x][y])
            continue;
          vis[x][y] = 1;
          for (int k = 0; k < 4; k++) {
            if (x + ax[k] >= 1 + cg and x + ax[k] <= n - cg and
                y + ay[k] >= 1 + cg and y + ay[k] <= n - cg)
              if (dp[now][x + ax[k]][y + ay[k]] <
                  min(dp[now][x][y], sig[x + ax[k]][y + ay[k]])) {

                dp[now][x + ax[k]][y + ay[k]] =
                    min(dp[now][x][y], sig[x + ax[k]][y + ay[k]]);
                wait[dp[now][x + ax[k]][y + ay[k]]].push_back(
                    mp(x + ax[k], y + ay[k]));
              }
          }
        }
        wait[i].clear();
      }

  for (int i = 1 + cg - 1; i <= n - cg + 1; i++)
    for (int j = 1 + cg - 1; j <= n - cg + 1; j++)
      for (int k = 0; k < 4; k++)
        if (dp[now][i][j] >= sig[i + ax[k]][j + ay[k]])
          fst[i + ax[k]][j + ay[k]] = min(fst[i + ax[k]][j + ay[k]], eg);
}
signed main() {
  scanf("%d", &n);
  for (int i = 1; i <= n * n; i++) {
    int x = i;
    scanf("%d", &x);
    sig[(x - 1) / n + 1][(x - 1) % n + 1] = n * n + 1 - i;
  }

  memset(fst, 0x3f, sizeof fst);
  int now = 0;
  for (int i = 1; i <= n; i++)
    dp[now][1][i] = sig[1][i], dp[now][n][i] = sig[n][i],
    dp[now][i][1] = sig[i][1], dp[now][i][n] = sig[i][n];
  for (int g = 1; g <= n; g++) {
    now ^= 1;
    spread(now ^ 1, g - 1);

    int bad = 0;
    memset(dp[now], 0, sizeof dp[now]);
    int cg = g - 1;
    for (int i = 1 + cg - 1; i <= 1 + n - cg; i++)
      for (int j = 1 + cg - 1; j <= 1 + n - cg; j++)
        if (min(i - 1, n - i) <= g - 1 or min(j - 1, n - j) <= g - 1)
          upd(dp[now][i][j], n * n);
    //	cg=0;
    for (int i = 1 + cg - 1; i <= 1 + n - cg; i++)
      for (int j = 1 + cg - 1; j <= 1 + n - cg; j++) {
        for (int k = 0; k < 5; k++)
          upd(dp[now][i + ax[k]][j + ay[k]], dp[now ^ 1][i][j]);
        if (fst[i][j] > n + n)
          bad = 1;
      }
    if (!bad)
      break;
  }
  for (int i = 2; i < n; i++)
    for (int j = 2; j < n; j++)
      ans += fst[i][j];
  cout << ans;
  return 0;
}

Error: TLE

Fixed submission:

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

int dp[2][nn][nn];
int sig[nn][nn];
void upd(int &x, int y) { x = max(x, y); }
int n;
int fst[nn][nn];
int ans = 0;
int ax[] = {-1, 1, 0, 0, 0}, ay[] = {0, 0, -1, 1, 0};

#define pii pair<int, int>
#define mp make_pair
vector<pii> wait[nn * nn];
int vis[nn][nn];
void spread(int now, int cg) {
  int eg = cg;
  vector<int> all;
  for (int i = 1 + cg - 1; i <= 1 + n - cg; i++)
    for (int j = 1 + cg - 1; j <= 1 + n - cg; j++)
      if (i and j and i <= n and j <= n)
        vis[i][j] = 0, wait[dp[now][i][j]].push_back(mp(i, j)),
        all.push_back(dp[now][i][j]), all.push_back(sig[i][j]);

  if (all.size() <= n * 10) {
    sort(all.begin(), all.end());
    for (int ii = 0; ii < all.size(); ii++)
      if (wait[all[ii]].size()) {
        int i = all[ii];
        for (int e = 0; e < wait[i].size(); e++) {
          pii p = wait[i][e];
          int x = p.first, y = p.second;
          if (vis[x][y])
            continue;
          vis[x][y] = 1;
          for (int k = 0; k < 4; k++) {
            if (x + ax[k] >= 1 + cg and x + ax[k] <= n - cg and
                y + ay[k] >= 1 + cg and y + ay[k] <= n - cg)
              if (dp[now][x + ax[k]][y + ay[k]] <
                  min(dp[now][x][y], sig[x + ax[k]][y + ay[k]])) {

                dp[now][x + ax[k]][y + ay[k]] =
                    min(dp[now][x][y], sig[x + ax[k]][y + ay[k]]);
                wait[dp[now][x + ax[k]][y + ay[k]]].push_back(
                    mp(x + ax[k], y + ay[k]));
              }
          }
        }
        wait[i].clear();
      }
  }

  for (int i = n * n; i >= 1; i--)
    if (wait[i].size()) {
      for (int e = 0; e < wait[i].size(); e++) {
        pii p = wait[i][e];
        int x = p.first, y = p.second;
        if (vis[x][y])
          continue;
        vis[x][y] = 1;
        for (int k = 0; k < 4; k++) {
          if (x + ax[k] >= 1 + cg and x + ax[k] <= n - cg and
              y + ay[k] >= 1 + cg and y + ay[k] <= n - cg)
            if (dp[now][x + ax[k]][y + ay[k]] <
                min(dp[now][x][y], sig[x + ax[k]][y + ay[k]])) {

              dp[now][x + ax[k]][y + ay[k]] =
                  min(dp[now][x][y], sig[x + ax[k]][y + ay[k]]);
              wait[dp[now][x + ax[k]][y + ay[k]]].push_back(
                  mp(x + ax[k], y + ay[k]));
            }
        }
      }
      wait[i].clear();
    }

  for (int i = 1 + cg - 1; i <= n - cg + 1; i++)
    for (int j = 1 + cg - 1; j <= n - cg + 1; j++)
      for (int k = 0; k < 4; k++)
        if (dp[now][i][j] >= sig[i + ax[k]][j + ay[k]])
          fst[i + ax[k]][j + ay[k]] = min(fst[i + ax[k]][j + ay[k]], eg);
}
signed main() {
  scanf("%d", &n);
  for (int i = 1; i <= n * n; i++) {
    int x = i;
    scanf("%d", &x);
    sig[(x - 1) / n + 1][(x - 1) % n + 1] = n * n + 1 - i;
  }

  memset(fst, 0x3f, sizeof fst);
  int now = 0;
  for (int i = 1; i <= n; i++)
    dp[now][1][i] = sig[1][i], dp[now][n][i] = sig[n][i],
    dp[now][i][1] = sig[i][1], dp[now][i][n] = sig[i][n];
  for (int g = 1; g <= n; g++) {
    now ^= 1;
    spread(now ^ 1, g - 1);

    int bad = 0;
    memset(dp[now], 0, sizeof dp[now]);
    int cg = g - 1;
    for (int i = 1 + cg - 1; i <= 1 + n - cg; i++)
      for (int j = 1 + cg - 1; j <= 1 + n - cg; j++)
        if (min(i - 1, n - i) <= g - 1 or min(j - 1, n - j) <= g - 1)
          upd(dp[now][i][j], n * n);
    //	cg=0;
    for (int i = 1 + cg - 1; i <= 1 + n - cg; i++)
      for (int j = 1 + cg - 1; j <= 1 + n - cg; j++) {
        for (int k = 0; k < 5; k++)
          upd(dp[now][i + ax[k]][j + ay[k]], dp[now ^ 1][i][j]);
        if (fst[i][j] > n + n)
          bad = 1;
      }
    if (!bad)
      break;
  }
  for (int i = 2; i < n; i++)
    for (int j = 2; j < n; j++)
      ans += fst[i][j];
  cout << ans;
  return 0;
}