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

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 7;
// const int MAXN = 1e3+7;

int X[MAXN], Y[MAXN];
int idX[MAXN];

int p[MAXN], q[MAXN];
int bam[MAXN], dan[MAXN];
int n;

int durotto(int i, int j) {
  i = idX[i];
  j = idX[j];
  return abs(X[i] - X[j]) + abs(Y[i] - Y[j]);
}

// int counter;
map<int, LL> dp[2][MAXN];
LL solve(int l, int r, bool side, int mn, int mx) {
  auto it = dp[side][l].find(r);
  if (it != dp[side][l].end())
    return it->second;

  vector<int> options;
  if (l > 1 && (p[l - 1] == mn - 1 || p[l - 1] == mx + 1)) {
    options.push_back(0);
  }
  if (r < n && (p[r + 1] == mn - 1 || p[r + 1] == mx + 1)) {
    options.push_back(1);
  }

  LL ans = 0;
  if (options.size() == 0) {
    ans = l - r;
  } else if (options.size() == 1) {
    if (options[0] == 0) {
      int _l = bam[l - 1];
      ans = solve(_l, r, false, min(mn, p[_l]), max(mx, p[_l]));
      ans += (side ? durotto(r, _l) : durotto(l, _l));
    } else {
      int _r = dan[r + 1];
      ans = solve(l, _r, true, min(mn, p[_r]), max(mx, p[_r]));
      ans += (side ? durotto(r, _r) : durotto(l, _r));
    }
  } else if (options.size() == 2) {
    ans = 1e15;
    int _l = bam[l - 1];
    int _r = dan[r + 1];
    int _mn = min(mn, min(p[_l], p[_r]));
    int _mx = max(mx, max(p[_l], p[_r]));
    {
      LL tmp = solve(_l, _r, true, _mn, _mx);
      if (side) {
        tmp += durotto(r, _l) * 2 + durotto(r, _r);
      } else {
        tmp += durotto(l, _l) * 2 + durotto(l, _r);
      }
      ans = min(ans, tmp);
    }
    {
      LL tmp = solve(_l, _r, false, _mn, _mx);
      if (side) {
        tmp += durotto(r, _r) * 2 + durotto(r, _l);
      } else {
        tmp += durotto(l, _r) * 2 + durotto(l, _l);
      }
      ans = min(ans, tmp);
    }
  }

  //    counter++;
  //    cout << options.size() << " options" << endl;
  //    cout << "dp[" << side << "][" << l << "][" << r << "] = " << ans <<
  //    endl;
  return dp[side][l][r] = ans;
}

LL ans[MAXN];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;

  vector<int> idY(n, 0);
  for (int i = 1; i <= n; i++) {
    cin >> X[i] >> Y[i];
    idX[i] = i;
    idY[i - 1] = i;
  }

  sort(idX + 1, idX + n + 1, [&](int i, int j) { return X[i] < X[j]; });
  sort(idY.begin(), idY.end(), [&](int i, int j) { return Y[i] < Y[j]; });
  for (int i = 0; i < n; i++) {
    q[idY[i]] = i + 1;
    //        cout << "q[" << idY[i] << "] = " << i+1 << endl;
  }
  for (int i = 1; i <= n; i++) {
    p[i] = q[idX[i]];
    //        cout << p[i] << " ";
  }
  //    cout << endl;

  bam[1] = 1;
  for (int i = 2; i <= n; i++) {
    bam[i] = i;
    if (abs(p[i] - p[i - 1]) == 1)
      bam[i] = bam[i - 1];
  }
  dan[n] = n;
  for (int i = n - 1; i > 0; i--) {
    dan[i] = i;
    if (abs(p[i] - p[i + 1]) == 1)
      dan[i] = dan[i + 1];
  }

  for (int i = 1; i <= n; i++) {
    ans[idX[i]] = solve(i, i, false, p[i], p[i]);
  }

  //    cout << "counter: " << counter << endl;

  for (int i = 1; i <= n; i++) {
    cout << ans[i] << "\\n";
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 7;
// const int MAXN = 1e3+7;

int X[MAXN], Y[MAXN];
int idX[MAXN];

int p[MAXN], q[MAXN];
int bam[MAXN], dan[MAXN];
int n;

int durotto(int i, int j) {
  i = idX[i];
  j = idX[j];
  return abs(X[i] - X[j]) + abs(Y[i] - Y[j]);
}

map<int, LL> dp[2][MAXN];
LL solve(int l, int r, bool side, int mn, int mx) {
  auto it = dp[side][l].find(r);
  if (it != dp[side][l].end())
    return it->second;

  vector<LL> options;
  if (l > 1 && (p[l - 1] == mn - 1 || p[l - 1] == mx + 1)) {
    LL tmp = solve(l - 1, r, false, min(mn, p[l - 1]), max(mx, p[l - 1]));
    tmp += (side ? durotto(l - 1, r) : durotto(l - 1, l)) - 1;
    options.push_back(tmp);
  }
  if (r < n && (p[r + 1] == mn - 1 || p[r + 1] == mx + 1)) {
    LL tmp = solve(l, r + 1, true, min(mn, p[r + 1]), max(mx, p[r + 1]));
    tmp += (side ? durotto(r, r + 1) : durotto(l, r + 1)) - 1;
    options.push_back(tmp);
  }
  LL ans = 0;
  if (options.size() >= 1) {
    ans = options.front();
    if (options.size() >= 2) {
      ans = min(ans, options[1]);
    }
  }
  return dp[side][l][r] = ans;
}

int ans[MAXN];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;

  vector<int> idY(n, 0);
  for (int i = 1; i <= n; i++) {
    cin >> X[i] >> Y[i];
    idX[i] = i;
    idY[i - 1] = i;
  }

  sort(idX + 1, idX + n + 1, [&](int i, int j) { return X[i] < X[j]; });
  sort(idY.begin(), idY.end(), [&](int i, int j) { return Y[i] < Y[j]; });
  for (int i = 0; i < n; i++) {
    q[idY[i]] = i + 1;
    //        cout << "q[" << idY[i] << "] = " << i+1 << endl;
  }
  for (int i = 1; i <= n; i++) {
    p[i] = q[idX[i]];
    //        cout << p[i+1] << " ";
  }
  //    cout << endl;

  bam[1] = 1;
  for (int i = 2; i <= n; i++) {
    bam[i] = i;
    if (abs(p[i] - p[i - 1]) == 1)
      bam[i] = bam[i - 1];
  }
  dan[n] = n;
  for (int i = n - 1; i > 0; i--) {
    dan[i] = i;
    if (abs(p[i] - p[i - 1]) == 1)
      dan[i] = dan[i + 1];
  }

  for (int i = 1; i <= n; i++) {
    ans[idX[i]] = solve(i, i, false, p[i], p[i]);
  }

  for (int i = 1; i <= n; i++) {
    cout << ans[i] << "\\n";
  }

  return 0;
}