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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <random>
#include <unordered_map>
#include <utility>

using namespace std;

struct Point {
  double x, y;
  Point *next;
};

uint64_t toKey(int x, int y) {
  union Key {
    uint64_t key;
    int x[2];
  };
  Key K;
  K.x[0] = x, K.x[1] = y;
  return K.key;
}

void build(unordered_map<uint64_t, Point *> &Grid, double d, int i, Point *P) {
  Grid.clear();
  for (int j = 0; j <= i; j++) {
    int x = floor(P[j].x / d), y = floor(P[j].y / d);
    uint64_t key = toKey(x, y);
    if (Grid.count(key) != 0) {
      P[j].next = Grid[key];
    }
    Grid[key] = &P[j];
  }
}

double distance(Point &a, Point &b) {
  return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

double search(unordered_map<uint64_t, Point *> &Grid, double d, Point &P) {
  int x = floor(P.x / d), y = floor(P.y / d);
  uint64_t key;
  double minimum = 1e10;
  for (int dx = -1; dx < 2; dx++) {
    for (int dy = -1; dy < 2; dy++) {
      key = toKey(x + dx, y + dy);
      if (Grid.count(key)) {
        Point *p = Grid[key];
        while (p != NULL) {
          if (minimum > distance(*p, P))
            minimum = distance(*p, P);
          p = p->next;
        }
      }
    }
  }
  return minimum;
}

void insert(unordered_map<uint64_t, Point *> &Grid, double d, Point &P) {
  int x = floor(P.x / d), y = floor(P.y / d);
  uint64_t key = toKey(x, y);
  if (Grid.count(key) != 0) {
    P.next = Grid[key];
  }
  Grid[key] = &P;
}

int main() {
  int n;
  cin >> n;
  Point P[n];
  for (int i = 0; i < n; i++) {
    cin >> P[i].x >> P[i].y;
    P[i].next = NULL;
  }
  //??????????????£???????????????
  random_device rd;
  mt19937 mt(rd()); //?????????????????§?????????????????????????????????
  uniform_int_distribution<int> dist(0, n - 1);
  for (int i = 0; i < n; i++) {
    int j = dist(mt);
    Point p = P[i];
    P[i] = P[j];
    P[j] = p;
  }
  unordered_map<uint64_t, Point *> Grid;
  double delta = distance(P[0], P[1]);
  build(Grid, delta, 1, P);
  for (int i = 2; i < n; i++) {
    double d2 = search(Grid, delta, P[i]);
    if (d2 >= delta) {
      insert(Grid, delta, P[i]);
    } else {
      delta = d2;
      build(Grid, delta, i, P);
    }
  }
  cout.precision(6);
  cout << fixed;
  cout << delta << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <random>
#include <unordered_map>
#include <utility>

using namespace std;

struct Point {
  double x, y;
  Point *next;
};

uint64_t toKey(int x, int y) {
  union Key {
    uint64_t key;
    int x[2];
  };
  Key K;
  K.x[0] = x, K.x[1] = y;
  return K.key;
}

void build(unordered_map<uint64_t, Point *> &Grid, double d, int i, Point *P) {
  Grid.clear();
  for (int j = 0; j <= i; j++) {
    int x = floor(P[j].x / d), y = floor(P[j].y / d);
    uint64_t key = toKey(x, y);
    if (Grid.count(key) != 0) {
      P[j].next = Grid[key];
    }
    Grid[key] = &P[j];
  }
}

double distance(Point &a, Point &b) {
  return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

double search(unordered_map<uint64_t, Point *> &Grid, double d, Point &P) {
  int x = floor(P.x / d), y = floor(P.y / d);
  uint64_t key;
  double minimum = 1e10;
  for (int dx = -1; dx < 2; dx++) {
    for (int dy = -1; dy < 2; dy++) {
      key = toKey(x + dx, y + dy);
      if (Grid.count(key)) {
        Point *p = Grid[key];
        while (p != NULL) {
          if (minimum > distance(*p, P))
            minimum = distance(*p, P);
          p = p->next;
        }
      }
    }
  }
  return minimum;
}

void insert(unordered_map<uint64_t, Point *> &Grid, double d, Point &P) {
  int x = floor(P.x / d), y = floor(P.y / d);
  uint64_t key = toKey(x, y);
  if (Grid.count(key) != 0) {
    P.next = Grid[key];
  }
  Grid[key] = &P;
}

int main() {
  int n;
  cin >> n;
  Point P[n];
  for (int i = 0; i < n; i++) {
    cin >> P[i].x >> P[i].y;
    P[i].next = NULL;
  }
  //??????????????£???????????????
  random_device rd;
  mt19937 mt(rd()); //?????????????????§?????????????????????????????????
  uniform_int_distribution<int> dist(0, n - 1);
  for (int i = 0; i < n; i++) {
    int j = dist(mt);
    Point p = P[i];
    P[i] = P[j];
    P[j] = p;
  }
  unordered_map<uint64_t, Point *> Grid;
  double delta = distance(P[0], P[1]);
  build(Grid, delta, 1, P);
  for (int i = 2; i < n; i++) {
    double d2 = search(Grid, delta, P[i]);
    if (d2 > delta) {
      insert(Grid, delta, P[i]);
    } else {
      delta = d2;
      build(Grid, delta, i, P);
    }
  }
  cout.precision(6);
  cout << fixed;
  cout << delta << endl;
  return 0;
}