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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

using namespace std;
using lint = long long;
using P = pair<lint, lint>;

#define rep(i, n) for (lint i = 0; i < (n); ++i)
#define rep1(i, n) for (lint i = 1; i < (n); ++i)
#define repn(i, a, b) for (lint i = (a); i < (b); ++i)
#define rep_inv(i, n) for (lint i = (n); i >= 0; --i)
#define rep_inv1(i, n) for (lint i = (n); i >= 1; --i)
#define all(vec) (vec).begin(), (vec).end()
#define cend printf("\\n")

constexpr lint Mod = /**/ 1000'000'007LL /*/ 998'244'353LL /**/;
constexpr lint Inf = 4'500'000'000'000'000'007LL; // 4.5e18+7
constexpr double Pi = 3.141592653589793;

template <class T> using prique = priority_queue<T>;
template <class T> using prique_inv = priority_queue<T, vector<T>, greater<T>>;
template <class T> inline T read() {
  T x{};
  cin >> x;
  return x;
}
template <class T> inline bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline istream &operator>>(istream &is, vector<T> &v) {
  for (auto &e : v)
    is >> e;
  return is;
}
template <class T> inline ostream &operator<<(ostream &os, const vector<T> &v) {
  size_t i = 0, n = v.size();
  for (const auto &e : v) {
    os << e;
    if (i + 1 < n)
      os << " ";
    ++i;
  }
  return os;
}
template <class T, class U>
inline istream &operator>>(istream &is, pair<T, U> &rhs) {
  return is >> rhs.first >> rhs.second;
}
template <class T, class U>
inline ostream &operator<<(ostream &os, const pair<T, U> &rhs) {
  return os << "{" << rhs.first << ", " << rhs.second << "}";
}
template <class T, class U> inline void print(const T &a, const U &b, bool f) {
  if (f)
    cout << a << "\\n";
  else
    cout << b << "\\n";
}
template <class InputIterator>
void arrin(InputIterator first, InputIterator last) {
  for (; first != last; ++first)
    cin >> (*first);
}
template <class InputIterator>
void arrout(InputIterator first, InputIterator last) {
  for (; first != last; ++first) {
    cout << (*first) << ((first + 1) != last ? " " : "\\n");
  }
}
template <class Head, class... Tail> tuple<Head, Tail...> reads() {
  Head head;
  cin >> head;

  const tuple<Head> &tup = std::make_tuple(head);

  if constexpr (sizeof...(Tail) == 0)
    return tup;
  else
    return std::tuple_cat(tup, reads<Tail...>());
}

bool pri(lint x) {
  for (lint i = 2; i * i <= x; ++i) {
    if (x % i == 0)
      return false;
  }
  return 1 < x;
}

lint fact[3'000'000];
void fact_init(lint n, lint m = Mod) {
  if (3'000'000 <= n)
    return;
  fact[0] = fact[1] = 1;
  for (lint i = 2; i <= n; ++i) {
    fact[i] = i * fact[i - 1] % m;
  }
}

lint modpow(lint x, lint n, lint m = Mod) {
  lint res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * x % m;
    x = x * x % m;
    n >>= 1;
  }
  return res;
}

lint intpow(lint x, lint n) {
  lint res = 1;
  while (n > 0) {
    if (n & 1)
      res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}

lint comb(lint n, lint r, lint m = Mod) {
  if (r == 0 || r == n)
    return 1;
  lint res = fact[n] * modpow(fact[n - r], m - 2, m) % m *
             modpow(fact[r], m - 2, m) % m;
  return res < 0 ? res + m : res;
}

map<lint, lint> factring(lint n) {
  map<lint, lint> res;
  for (lint i = 2; i * i <= n; ++i) {
    while (n % i == 0) {
      n /= i;
      ++res[i];
    }
  }
  if (n != 1)
    ++res[n];
  return res;
}

int main() {
  lint n;
  cin >> n;

  lint max_u = -2000'000'000, min_u = +2000'000'000, max_v = -2000'000'000,
       min_v = +2000'000'000;

  rep(i, n) {
    lint x, y;
    cin >> x >> y;

    const lint u = x + y, v = x - y;

    chmax(max_u, u);
    chmin(min_u, u);
    chmax(max_v, v);
    chmin(min_v, v);
  }

  cout << max(max_u - min_u, max_v - min_v) << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

using namespace std;
using lint = long long;
using P = pair<lint, lint>;

#define rep(i, n) for (lint i = 0; i < (n); ++i)
#define rep1(i, n) for (lint i = 1; i < (n); ++i)
#define repn(i, a, b) for (lint i = (a); i < (b); ++i)
#define rep_inv(i, n) for (lint i = (n); i >= 0; --i)
#define rep_inv1(i, n) for (lint i = (n); i >= 1; --i)
#define all(vec) (vec).begin(), (vec).end()
#define cend printf("\\n")

constexpr lint Mod = /**/ 1000'000'007LL /*/ 998'244'353LL /**/;
constexpr lint Inf = 4'500'000'000'000'000'007LL; // 4.5e18+7
constexpr double Pi = 3.141592653589793;

template <class T> using prique = priority_queue<T>;
template <class T> using prique_inv = priority_queue<T, vector<T>, greater<T>>;
template <class T> inline T read() {
  T x{};
  cin >> x;
  return x;
}
template <class T> inline bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline istream &operator>>(istream &is, vector<T> &v) {
  for (auto &e : v)
    is >> e;
  return is;
}
template <class T> inline ostream &operator<<(ostream &os, const vector<T> &v) {
  size_t i = 0, n = v.size();
  for (const auto &e : v) {
    os << e;
    if (i + 1 < n)
      os << " ";
    ++i;
  }
  return os;
}
template <class T, class U>
inline istream &operator>>(istream &is, pair<T, U> &rhs) {
  return is >> rhs.first >> rhs.second;
}
template <class T, class U>
inline ostream &operator<<(ostream &os, const pair<T, U> &rhs) {
  return os << "{" << rhs.first << ", " << rhs.second << "}";
}
template <class T, class U> inline void print(const T &a, const U &b, bool f) {
  if (f)
    cout << a << "\\n";
  else
    cout << b << "\\n";
}
template <class InputIterator>
void arrin(InputIterator first, InputIterator last) {
  for (; first != last; ++first)
    cin >> (*first);
}
template <class InputIterator>
void arrout(InputIterator first, InputIterator last) {
  for (; first != last; ++first) {
    cout << (*first) << ((first + 1) != last ? " " : "\\n");
  }
}
template <class Head, class... Tail> tuple<Head, Tail...> reads() {
  Head head;
  cin >> head;

  const tuple<Head> &tup = std::make_tuple(head);

  if constexpr (sizeof...(Tail) == 0)
    return tup;
  else
    return std::tuple_cat(tup, reads<Tail...>());
}

bool pri(lint x) {
  for (lint i = 2; i * i <= x; ++i) {
    if (x % i == 0)
      return false;
  }
  return 1 < x;
}

lint fact[3'000'000];
void fact_init(lint n, lint m = Mod) {
  if (3'000'000 <= n)
    return;
  fact[0] = fact[1] = 1;
  for (lint i = 2; i <= n; ++i) {
    fact[i] = i * fact[i - 1] % m;
  }
}

lint modpow(lint x, lint n, lint m = Mod) {
  lint res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * x % m;
    x = x * x % m;
    n >>= 1;
  }
  return res;
}

lint intpow(lint x, lint n) {
  lint res = 1;
  while (n > 0) {
    if (n & 1)
      res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}

lint comb(lint n, lint r, lint m = Mod) {
  if (r == 0 || r == n)
    return 1;
  lint res = fact[n] * modpow(fact[n - r], m - 2, m) % m *
             modpow(fact[r], m - 2, m) % m;
  return res < 0 ? res + m : res;
}

map<lint, lint> factring(lint n) {
  map<lint, lint> res;
  for (lint i = 2; i * i <= n; ++i) {
    while (n % i == 0) {
      n /= i;
      ++res[i];
    }
  }
  if (n != 1)
    ++res[n];
  return res;
}

struct Point {
  lint x, y;

  Point() : x(0), y(0) {}
  Point(lint x, lint y) : x(x), y(y) {}

  bool operator<(Point p) const {
    if (x != p.x)
      return x < p.x;
    return y < p.y;
  }

  Point operator+(Point p) const { return Point(x + p.x, y - p.y); }

  Point operator-(Point p) const { return Point(x - p.x, y - p.y); }

  lint cross(Point p) const { return x * p.y - y * p.x; }

  lint distanceFromSq(Point p) const {
    return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
  }

  lint manhattanDistanceFrom(Point p) const {
    return abs(x - p.x) + abs(y - p.y);
  }

  friend istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

  friend ostream &operator<<(ostream &os, const Point &p) {
    return os << "(" << p.x << ", " << p.y << ")";
  }
};

// 凸包
vector<Point> convex_full(const vector<Point> &vec, lint n) {
  lint k = 0;
  vector<Point> res(n * 2);

  rep(i, n) {
    while (k > 1 && (res[k - 1] - res[k - 2]).cross(vec[i] - res[k - 1]) <= 0)
      k--;
    res[k++] = vec[i];
  }

  for (lint i = n - 2, t = k; i >= 0; --i) {
    while (k > t && (res[k - 1] - res[k - 2]).cross(vec[i] - res[k - 1]) <= 0)
      k--;
    res[k++] = vec[i];
  }

  res.resize(k - 1);
  return res;
}

// 最遠点対
lint diameter(const vector<Point> vec) {
  const vector<Point> &convex = convex_full(vec, vec.size());

  lint n = convex.size();

  if (n == 2) {
    return convex[0].distanceFromSq(convex[1]);
  }

  lint i = 0, j = 0;

  for (lint k = 0; k < n; ++k) {
    if (!(convex[i] < convex[k]))
      i = k;
    if (convex[j] < convex[k])
      j = k;
  }

  lint res = 0;
  lint si = i, sj = j;
  while (i != sj || j != si) {
    res = max(res, convex[i].distanceFromSq(convex[j]));

    if ((convex[(i + 1) % n] - convex[i])
            .cross(convex[(j + 1) % n] - convex[j]) < 0) {
      i = (i + 1) % n;
    } else {
      j = (j + 1) % n;
    }
  }

  return res;
}

int main() {
  lint n;
  cin >> n;
  vector<Point> v(n);

  rep(i, n) {
    /*lint x, y;
    cin >> x >> y;
    v[i] = { x - y,x + y };*/
    cin >> v[i];
  }

  // sort(all(v));

  const vector<Point> &convex = convex_full(v, v.size());

  lint ans = 0;

  lint m = convex.size();

  rep(i, m - 1) {
    repn(j, i, m) {
      ans = max(ans, convex[i].manhattanDistanceFrom(convex[j]));
    }
  }

  cout << ans << endl;
}