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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <utility>
#include <vector>

using namespace std;

static const double EPS = 1e-12;
static const double INF = 1e24;

using Point = complex<double>;
using Plane = vector<Point>;
using Polygon = vector<Point>;

bool operator<(const Point &a, const Point &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}

double cross_prod(const Point &a, const Point &b) { return imag(conj(a) * b); }

double dot_prod(const Point &a, const Point &b) { return real(conj(a) * b); }

enum {
  ONLINE_FRONT = -2,
  CLOCKWISE,
  ON_SEGMENT,
  COUNTER_CLOCKWISE,
  ONLINE_BACK,
};

int ccwise(Point a, Point b, Point c) {
  b -= a;
  c -= a;

  if (cross_prod(b, c) > 0) {
    return COUNTER_CLOCKWISE;
  } else if (cross_prod(b, c) < 0) {
    return CLOCKWISE;
  } else if (dot_prod(b, c) < 0) {
    return ONLINE_BACK;
  } else if (norm(b) < norm(c)) {
    return ONLINE_FRONT;
  } else {
    return ON_SEGMENT;
  }
}

template <class LineType> int ccwise(LineType l, Point p) {
  return ccwise(l.first, l.second, p);
}

struct Line : public pair<Point, Point> {
  Line() {}
  Line(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

struct LineSeg : public pair<Point, Point> {
  LineSeg() {}
  LineSeg(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

pair<Point, Point> closest_pair(Polygon g) {
  size_t V = g.size(), s = 0, t = 1, m = 2;
  vector<size_t> S(V);
  sort(g.begin(), g.end(), [](const Point &a, const Point &b) {
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  });

  double res = abs(g[s] - g[t]);
  for (size_t i = 2; i < V; S[m++] = i++)
    for (size_t j = 0; j < m; ++j) {
      if (res > abs(g[S[j]] - g[i]))
        res = abs(g[s = S[j]] - g[t = i]);

      if (real(g[S[j]]) < real(g[i] - res))
        S[j--] = S[--m];
    }

  return make_pair(g[s], g[t]);
}

template <class RandomIt>
pair<Point, Point> closest_pair(RandomIt first, RandomIt last) {
  size_t n = last - first;
  if (n < 2)
    return make_pair(Point(-INF, -INF), Point(INF, INF));

  RandomIt mid = first + n / 2;
  double x = real(*mid);
  pair<Point, Point> p1 = closest_pair(first, mid);
  pair<Point, Point> p2 = closest_pair(mid, last);
  inplace_merge(first, mid, last, [](const Point &lhs, const Point &rhs) {
    return imag(lhs) < imag(rhs);
  });

  double d1 = norm(p1.first - p1.second), d2 = norm(p2.first - p2.second);
  double d = (d1 < d2 ? d1 : d2);
  pair<Point, Point> res = (d1 < d2 ? p1 : p2);

  vector<Point> b;
  for (RandomIt it = first; it < last; ++it) {
    if (norm(real(*it) - x) >= d)
      continue;

    for (size_t j = 0; j < b.size(); ++j) {
      Point e = *it - b[b.size() - j - 1];
      if (imag(e) >= sqrt(d))
        break;

      if (d > norm(e)) {
        d = norm(e);
        res = make_pair(*it, b[b.size() - j - 1]);
      }
    }
    b.push_back(*it);
  }

  return res;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  Polygon g(n);
  for (size_t i = 0; i < n; ++i) {
    double x, y;
    scanf("%lf %lf", &x, &y);
    g[i] = Point(x, y);
  }

  sort(g.begin(), g.end(), [](const Point &lhs, const Point &rhs) {
    return real(lhs) != real(rhs) ? real(lhs) < real(rhs)
                                  : imag(lhs) < imag(rhs);
  });

  pair<Point, Point> p = closest_pair(g.begin(), g.end());
  printf("%.9f\\n", abs(p.first - p.second));
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <utility>
#include <vector>

using namespace std;

static const double EPS = 1e-12;
static const double INF = 1e24;

using Point = complex<double>;
using Plane = vector<Point>;
using Polygon = vector<Point>;

bool operator<(const Point &a, const Point &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}

double cross_prod(const Point &a, const Point &b) { return imag(conj(a) * b); }

double dot_prod(const Point &a, const Point &b) { return real(conj(a) * b); }

enum {
  ONLINE_FRONT = -2,
  CLOCKWISE,
  ON_SEGMENT,
  COUNTER_CLOCKWISE,
  ONLINE_BACK,
};

int ccwise(Point a, Point b, Point c) {
  b -= a;
  c -= a;

  if (cross_prod(b, c) > 0) {
    return COUNTER_CLOCKWISE;
  } else if (cross_prod(b, c) < 0) {
    return CLOCKWISE;
  } else if (dot_prod(b, c) < 0) {
    return ONLINE_BACK;
  } else if (norm(b) < norm(c)) {
    return ONLINE_FRONT;
  } else {
    return ON_SEGMENT;
  }
}

template <class LineType> int ccwise(LineType l, Point p) {
  return ccwise(l.first, l.second, p);
}

struct Line : public pair<Point, Point> {
  Line() {}
  Line(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

struct LineSeg : public pair<Point, Point> {
  LineSeg() {}
  LineSeg(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

pair<Point, Point> closest_pair(Polygon g) {
  size_t V = g.size(), s = 0, t = 1, m = 2;
  vector<size_t> S(V);
  sort(g.begin(), g.end(), [](const Point &a, const Point &b) {
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  });

  double res = abs(g[s] - g[t]);
  for (size_t i = 2; i < V; S[m++] = i++)
    for (size_t j = 0; j < m; ++j) {
      if (res > abs(g[S[j]] - g[i]))
        res = abs(g[s = S[j]] - g[t = i]);

      if (real(g[S[j]]) < real(g[i] - res))
        S[j--] = S[--m];
    }

  return make_pair(g[s], g[t]);
}

int main() {
  size_t n;
  scanf("%zu", &n);

  Polygon g(n);
  for (size_t i = 0; i < n; ++i) {
    double x, y;
    scanf("%lf %lf", &x, &y);
    g[i] = Point(x, y);
  }

  pair<Point, Point> p = closest_pair(g);
  printf("%.16f\\n", abs(p.first - p.second));
  return 0;
}