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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>

using namespace std;
typedef long long ll;

const int MAX_N = 100001;
int H, W;
int N;
int XS[MAX_N];
int YS[MAX_N];
int curLast;
vector<int> xnums;
vector<int> ynums;
// ¶a
ll leftDistSumX[MAX_N];
ll leftDistSumY[MAX_N];
// Ea
ll rightDistSumX[MAX_N];
ll rightDistSumY[MAX_N];
map<int, int> xStartPos;
map<int, int> yStartPos;

ll check(ll s, bool isX = true) {
  ll sum = 0;
  // ÀWsªÇÌ_ÆÇÌ_ÌÔÉ é©ð©Â¯é
  // »Ìîñð³ÉAÚ®ÊðvZ
  if (isX) {
    // ßÄsÈãÆÈéÓð©Â¯é
    vector<int>::iterator it = lower_bound(xnums.begin(), xnums.end(), s);
    if (it == xnums.end())
      sum = leftDistSumX[N - 1] + rightDistSumX[N - 1] + abs(s - xnums[N - 1]);
    else if (it == xnums.begin())
      sum = leftDistSumX[0] + rightDistSumX[0] + abs(s - xnums[0]);
    else {
      sum =
          leftDistSumX[it - xnums.begin()] + rightDistSumX[it - xnums.begin()];
      if (*it != s) {
        // ¢­Âß·Kvª é©
        ll back = *it - s;
        ll leftCnt = xStartPos[*it];
        ll rightCnt = N - leftCnt;
        sum -= leftCnt * back;
        sum += rightCnt * back;
      }
    }
    sum *= 2;
    sum -= abs(s - XS[curLast]);
  } else {
    // ßÄsÈãÆÈéÓð©Â¯é
    vector<int>::iterator it = lower_bound(ynums.begin(), ynums.end(), s);
    if (it == ynums.end())
      sum = leftDistSumY[N - 1] + rightDistSumY[N - 1] + abs(s - ynums[N - 1]);
    else if (it == ynums.begin())
      sum = leftDistSumY[0] + rightDistSumY[0] + abs(s - ynums[0]);
    else {
      sum =
          leftDistSumY[it - ynums.begin()] + rightDistSumY[it - ynums.begin()];
      if (*it != s) {
        // ¢­Âß·Kvª é©
        ll back = -s + *it;
        ll leftCnt = yStartPos[*it];
        ll rightCnt = N - leftCnt;
        sum -= leftCnt * back;
        sum += rightCnt * back;
      }
    }
    sum *= 2;
    sum -= abs(s - YS[curLast]);
  }
  return sum;
}

int main() {
  cin >> W >> H;
  cin >> N;
  for (int i = 0; i < N; i++)
    cin >> XS[i] >> YS[i];
  // xûüÌÝÏa
  for (int i = 0; i < N; i++)
    xnums.push_back(XS[i]);
  sort(xnums.begin(), xnums.end());
  for (int i = N - 1; i >= 0; i--)
    xStartPos[xnums[i]] = i;
  ll baseLeftSumX = 0;
  ll baseRightSumX = 0;
  for (int i = 1; i < N; i++)
    baseRightSumX += abs(xnums[i] - xnums[0]);
  for (int i = 0; i < N; i++) {
    rightDistSumX[i] = baseRightSumX;
    leftDistSumX[i] = baseLeftSumX;
    if (i != N - 1) {
      baseRightSumX -= (ll)abs(xnums[i] - xnums[i + 1]) * (N - i - 1);
      baseLeftSumX += (ll)abs(xnums[i] - xnums[i + 1]) * (i + 1);
    }
  }
  // yûüÌÝÏa
  for (int i = 0; i < N; i++)
    ynums.push_back(YS[i]);
  sort(ynums.begin(), ynums.end());
  for (int i = N - 1; i >= 0; i--)
    yStartPos[ynums[i]] = i;
  ll baseLeftSumY = 0;
  ll baseRightSumY = 0;
  for (int i = 1; i < N; i++)
    baseRightSumY += abs(ynums[i] - ynums[0]);
  for (int i = 0; i < N; i++) {
    rightDistSumY[i] = baseRightSumY;
    leftDistSumY[i] = baseLeftSumY;
    if (i != N - 1) {
      baseRightSumY -= (ll)abs(ynums[i] - ynums[i + 1]) * (N - i - 1);
      baseLeftSumY += (ll)abs(ynums[i] - ynums[i + 1]) * (i + 1);
    }
  }

  // Ç±ðÅãÉKêéêÉ·é©Åêí¯
  ll ret = -1;
  ll lastX, lastY;
  ll candX[3], candY[3];
  for (int lp = 0; lp < N; lp++) {
    curLast = lp;
    // x
    ll ub = 1000000000;
    ll lb = 0;
    while (ub - lb > 2) {
      ll mid1 = ((ub - lb) / 3) + lb;
      ll mid2 = ((ub - lb) / 3) * 2 + lb;
      if (check(mid1) < check(mid2))
        ub = mid2;
      else if (check(mid1) > check(mid2))
        lb = mid1;
      else
        lb = mid1;
    }
    candX[0] = lb;
    candX[1] = lb + 1;
    candX[2] = ub;
    ll minXVal = -1;
    ll rx;
    for (int i = 0; i < 3; i++) {
      ll tmp = check(candX[i]);
      if (minXVal == -1 || tmp < minXVal) {
        minXVal = tmp;
        rx = candX[i];
      }
    }
    // y
    ub = 1000000000;
    lb = 0;
    while (ub - lb > 2) {
      ll mid1 = ((ub - lb) / 3) + lb;
      ll mid2 = ((ub - lb) / 3) * 2 + lb;
      if (check(mid1, false) < check(mid2, false))
        ub = mid2;
      else if (check(mid1, false) > check(mid2, false))
        lb = mid1;
      else
        lb = mid1;
    }
    candY[0] = lb;
    candY[1] = lb + 1;
    candY[2] = ub;
    ll minYVal = -1;
    ll ry;
    for (int i = 0; i < 3; i++) {
      ll tmp = check(candY[i], false);
      if (minYVal == -1 || tmp < minYVal) {
        minYVal = tmp;
        ry = candY[i];
      }
    }
    ll res = minXVal + minYVal;
    if (ret == -1 || res < ret) {
      ret = res;
      lastX = rx;
      lastY = ry;
    } else if (res == ret) {
      if (lastX > rx) {
        lastX = rx;
        lastY = ry;
      } else if (lastX == rx) {
        if (lastY > ry) {
          lastX = rx;
          lastY = ry;
        }
      }
    }
  }
  std::cout << ret << endl;
  std::cout << lastX << " " << lastY << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>

using namespace std;
typedef long long ll;

const int MAX_N = 100001;
int H, W;
int N;
int XS[MAX_N];
int YS[MAX_N];
int curLast;

ll check(ll s, bool isX = true) {
  ll sum = 0;
  for (int i = 0; i < N; i++) {
    int co = 2;
    if (i == curLast)
      co = 1;
    if (isX)
      sum += co * abs(XS[i] - s);
    else
      sum += co * abs(YS[i] - s);
  }
  return sum;
}

int main() {
  cin >> W >> H;
  cin >> N;
  for (int i = 0; i < N; i++)
    cin >> XS[i] >> YS[i];
  // ツづつアツづーツ催古」ツづ可訪ツづェツづゥツ湘ェツ渉環づ可つキツづゥツつゥツづ湘ェツ債づュツつッ
  ll ret = -1;
  ll lastX, lastY;
  ll candX[3], candY[3];
  for (int i = 0; i < N; i++) {
    curLast = i;
    // x
    int cnt = 1000;
    ll ub = 1000000000;
    ll lb = 0;
    while (ub - lb > 2) {
      ll mid1 = ((ub - lb) / 3) + lb;
      ll mid2 = ((ub - lb) / 3) * 2 + lb;
      if (check(mid1) < check(mid2))
        ub = mid2;
      else if (check(mid1) > check(mid2))
        lb = mid1;
      else
        lb = mid1;
    }
    candX[0] = lb;
    candX[1] = lb + 1;
    candX[2] = ub;
    ll minXVal = -1;
    ll rx;
    for (int i = 0; i < 3; i++) {
      ll tmp = check(candX[i]);
      if (minXVal == -1 || tmp < minXVal) {
        minXVal = tmp;
        rx = candX[i];
      }
    }
    // y
    cnt = 1000;
    ub = 1000000000;
    lb = 0;
    while (ub - lb > 2) {
      ll mid1 = ((ub - lb) / 3) + lb;
      ll mid2 = ((ub - lb) / 3) * 2 + lb;
      if (check(mid1, false) < check(mid2, false))
        ub = mid2;
      else if (check(mid1, false) > check(mid2, false))
        lb = mid1;
      else
        lb = mid1;
    }
    candY[0] = lb;
    candY[1] = lb + 1;
    candY[2] = ub;
    ll minYVal = -1;
    ll ry;
    for (int i = 0; i < 3; i++) {
      ll tmp = check(candY[i], false);
      if (minYVal == -1 || tmp < minYVal) {
        minYVal = tmp;
        ry = candY[i];
      }
    }
    ll res = minXVal + minYVal;
    if (ret == -1 || res < ret) {
      ret = res;
      lastX = rx;
      lastY = ry;
    } else if (res == ret) {
      if (lastX > rx) {
        lastX = rx;
        lastY = ry;
      } else if (lastX == rx) {
        if (lastY > ry) {
          lastX = rx;
          lastY = ry;
        }
      }
    }
  }
  std::cout << ret << endl;
  std::cout << lastX << " " << lastY << endl;

  return 0;
}