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

#include <bits/stdc++.h>
#define MAX 100010
#define inf 1 << 29
#define linf 1e19
#define eps (1e-8)
#define mod 1000000007
#define pi acos(-1)
#define phi (1.0 + sqrt(5)) / 2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define pd(a) printf("%.10f\\n", (double)(a))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (a)-1; (b) <= i; i--)
#define equals(a, b) (fabs((a) - (b)) < eps)
using namespace std;
typedef long double ldouble;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, ldouble> pid;
typedef pair<ldouble, int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;

class Point {
public:
  ldouble x, y;
  Point(ldouble x = 0, ldouble y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(ldouble k) { return Point(x * k, y * k); }
  Point operator/(ldouble k) { return Point(x / k, y / k); }
  bool operator<(Point p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator==(Point p) const {
    return fabs(x - p.x) < eps && fabs(y - p.y) < eps;
  }

  ldouble abs() { return sqrt(norm()); }
  ldouble norm() { return (x * x + y * y); }
};
typedef Point Vector;
typedef vector<Point> Polygon;

ldouble norm(Vector a) { return (a.x * a.x + a.y * a.y); }
ldouble abs(Vector a) { return sqrt(norm(a)); }
ldouble dot(Vector a, Vector b) { return (a.x * b.x + a.y * b.y); }
ldouble cross(Vector a, Vector b) { return (a.x * b.y - a.y * b.x); }

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if (cross(a, b) > eps)
    return 1;
  if (cross(a, b) < -eps)
    return -1;
  if (dot(a, b) < -eps)
    return 2;
  if (a.norm() < b.norm())
    return -2;
  return 0;
}

int n;
vector<Point> p;

ldouble solve() {
  sort(all(p));
  ldouble res = linf;
  vector<Point> lu, ld, ru, rd;
  ldouble area1[MAX] = {}, area2[MAX] = {};
  ldouble area3[MAX] = {}, area4[MAX] = {};
  lu.pb(p[0]);
  ld.pb(p[0]);
  FOR(i, 1, n) {
    area1[i] = area1[i - 1];
    for (int j = lu.size() - 1; j >= 1 && ccw(lu[j - 1], lu[j], p[i]) == 1;
         j--) {
      area1[i] -= fabs(cross(lu[j - 1] - lu[j], lu[0] - lu[j])) / 2.0L;
      lu.pop_back();
    }
    area1[i] += fabs(cross(lu.back() - p[i], lu[0] - p[i])) / 2.0L;
    lu.pb(p[i]);
  }
  FOR(i, 1, n) {
    area2[i] = area2[i - 1];
    for (int j = ld.size() - 1; j >= 1 && ccw(ld[j - 1], ld[j], p[i]) == -1;
         j--) {
      area2[i] -= fabs(cross(ld[j - 1] - ld[j], ld[0] - ld[j])) / 2.0L;
      ld.pop_back();
    }
    area2[i] += fabs(cross(ld.back() - p[i], ld[0] - p[i])) / 2.0L;
    ld.pb(p[i]);
  }
  reverse(all(p));
  ru.pb(p[0]);
  rd.pb(p[0]);
  FOR(i, 1, n) {
    area3[i] = area3[i - 1];
    for (int j = ru.size() - 1; j >= 1 && ccw(ru[j - 1], ru[j], p[i]) == -1;
         j--) {
      area3[i] -= fabs(cross(ru[j - 1] - ru[j], ru[0] - ru[j])) / 2.0L;
      ru.pop_back();
    }
    area3[i] += fabs(cross(ru.back() - p[i], ru[0] - p[i])) / 2.0L;
    ru.pb(p[i]);
  }
  FOR(i, 1, n) {
    area4[i] = area4[i - 1];
    for (int j = rd.size() - 1; j >= 1 && ccw(rd[j - 1], rd[j], p[i]) == 1;
         j--) {
      area4[i] -= fabs(cross(rd[j - 1] - rd[j], rd[0] - rd[j])) / 2.0L;
      rd.pop_back();
    }
    area4[i] += fabs(cross(rd.back() - p[i], rd[0] - p[i])) / 2.0L;
    rd.pb(p[i]);
  }
  reverse(all(p));
  FOR(i, 0, n - 1) {
    if (p[i].x == p[i + 1].x)
      continue;
    res = min(res, area1[i] + area2[i] + area3[n - i - 2] + area4[n - i - 2]);
  }
  if (res == linf)
    return 0;
  return (0.5L + res);
}

int main() {
  cin >> n;
  p.resize(n);
  FOR(i, 0, n) cin >> p[i].x >> p[i].y;
  printf("%ld\\n", (ull)solve());
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define MAX 100010
#define inf 1 << 29
#define linf 1e19
#define eps (1e-8)
#define mod 1000000007
#define pi acos(-1)
#define phi (1.0 + sqrt(5)) / 2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define pd(a) printf("%.10f\\n", (double)(a))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (a)-1; (b) <= i; i--)
#define equals(a, b) (fabs((a) - (b)) < eps)
using namespace std;
typedef long double ldouble;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, ldouble> pid;
typedef pair<ldouble, int> pdi;
typedef vector<int> vi;
typedef vector<pii> vpi;

class Point {
public:
  ldouble x, y;
  Point(ldouble x = 0, ldouble y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(ldouble k) { return Point(x * k, y * k); }
  Point operator/(ldouble k) { return Point(x / k, y / k); }
  bool operator<(Point p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator==(Point p) const {
    return fabs(x - p.x) < eps && fabs(y - p.y) < eps;
  }

  ldouble abs() { return sqrt(norm()); }
  ldouble norm() { return (x * x + y * y); }
};
typedef Point Vector;
typedef vector<Point> Polygon;

ldouble norm(Vector a) { return (a.x * a.x + a.y * a.y); }
ldouble abs(Vector a) { return sqrt(norm(a)); }
ldouble dot(Vector a, Vector b) { return (a.x * b.x + a.y * b.y); }
ldouble cross(Vector a, Vector b) { return (a.x * b.y - a.y * b.x); }

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  if (cross(a, b) > eps)
    return 1;
  if (cross(a, b) < -eps)
    return -1;
  if (dot(a, b) < -eps)
    return 2;
  if (a.norm() < b.norm())
    return -2;
  return 0;
}

ldouble Area(Polygon p) {
  ldouble area = 0.0L;
  int n = p.size();
  for (int i = 0; i < n; i++)
    area += cross(p[i], p[(i + 1) % n]);
  return abs(area) / 2.0L;
}

int n;
vector<Point> p;

ldouble solve() {
  sort(all(p));
  ldouble res = linf;
  vector<Point> lu, ld, ru, rd;
  ldouble area1[MAX] = {}, area2[MAX] = {};
  ldouble area3[MAX] = {}, area4[MAX] = {};
  FOR(i, 0, n) {
    for (int j = lu.size() - 1; j >= 1 && ccw(lu[j - 1], lu[j], p[i]) == 1; j--)
      lu.pop_back();
    lu.pb(p[i]);
    area1[i] = Area(lu);
  }
  FOR(i, 0, n) {
    for (int j = ld.size() - 1; j >= 1 && ccw(ld[j - 1], ld[j], p[i]) == -1;
         j--)
      ld.pop_back();
    ld.pb(p[i]);
    area2[i] = Area(ld);
  }
  reverse(all(p));
  FOR(i, 0, n) {
    for (int j = ru.size() - 1; j >= 1 && ccw(ru[j - 1], ru[j], p[i]) == -1;
         j--)
      ru.pop_back();
    ru.pb(p[i]);
    area3[i] = Area(ru);
  }
  FOR(i, 0, n) {
    for (int j = rd.size() - 1; j >= 1 && ccw(rd[j - 1], rd[j], p[i]) == 1; j--)
      rd.pop_back();
    rd.pb(p[i]);
    area4[i] = Area(rd);
  }
  reverse(all(p));
  FOR(i, 0, n - 1) {
    if (p[i].x == p[i + 1].x)
      continue;
    res = min(res, area1[i] + area2[i] + area3[n - i - 2] + area4[n - i - 2]);
  }
  return (0.5 + res);
}

int main() {
  cin >> n;
  p.resize(n);
  FOR(i, 0, n) cin >> p[i].x >> p[i].y;
  printf("%ld\\n", (ull)solve());
  return 0;
}