Problem:
問題 ４

　平面上の n 個の点 P1, ..., Pn が与えられたとき，
距離が最小の２点を求めたい．

　入力ファイルの１行目には整数 n が書いてある．
２行目から n+1 行目のそれぞれには，
２つの正整数 x, y が１つの半角空白文字を区切りとして書いてある．
i+1 行目の x, y はそれぞれ Pi の x 座標，
Pi の y 座標である．
これら n 点の中から最も近い２点を選んだとき，
この２点間の距離の２乗を出力せよ．

　ただし，
2≤n≤500000 かつ -10000≤x≤10000, -10000≤y≤10000 とし，
５つの入力ファイルのうち３つでは n≤100 である．
また，どの入力ファイルにおいても，全ての座標は異なるものとする．

出力ファイルにおいては，
出力の最後の行にも改行コードを入れること．

入出力例

入力例１

2
0 0
1 1

出力例１

2

入力例２

3
5 5
0 0
-3 -4

出力例２

25

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in C (judge verdict: Accepted)

// AOJ 585 Nearest Two Points
// 2017.9.24 bal4u
// 2018.3.17
// 2018.5.3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct { int x, y; } PP;

#define INF  0x10101010

#if 1
#define gc() getchar_unlocked()
#else
#define gc() getchar()
#endif
int in()
{
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

PP p[500005], L[500005], R[500005];

#define BASE 10000
#define VMAX 20002
int f[VMAX+1];
void distsort(int n, PP *ps, PP *po)
{
	int i, x;
	PP *p, *end;

	end = ps + n;
	for (p = ps; p < end; p++) f[BASE + p->x]++;
	for (i = 1; i <= VMAX; i++) f[i] += f[i-1];
	for (i = n-1; i >= 0; i--) {
		x = BASE + ps[i].x, po[--f[x]] = ps[i];
	}
}

void merge(PP *p, int low, int mid, int high)
{
	int n1, n2, i, j, k;

	n1 = mid-low, n2 = high-mid;
	memcpy(L, p+low, sizeof(PP)*n1);
	memcpy(R, p+mid, sizeof(PP)*n2);
	L[n1].y = R[n2].y = INF;

	i = 0, j = 0;
	for (k = low; k < high; k++) {
		if (L[i].y <= R[j].y) p[k] = L[i++];
		else                  p[k] = R[j++];
	}
}

int closest_pair(int n, PP *p)
{
	int m, i, j, t;
	int ans, d, x;

	if(n <= 1) return INF;
	m = n >> 1;
	x = p[m].x;
	ans = closest_pair(m, p);
	d   = closest_pair(n-m, p+m);
	if (d < ans) ans = d;
	merge(p, 0, m, n);

	t = 0;
	for (i = 0; i < n; i++) {
		d = p[i].x-x;
		if (d*d >= ans) continue;

		for (j = 0; j < t; j++) {
			int dx = p[i].x - L[t-1-j].x;
			int dy = p[i].y - L[t-1-j].y;
			int dy2 = dy*dy;
			if (dy2 >= ans) break;
			d = dx*dx + dy2;
			if (d < ans) ans = d;
		}
		L[t++] = p[i];
	}
	return ans;
}

int main()
{
	int n, i;

	n = in();
	for (i = 0; i < n; i++) L[i].x = in(), L[i].y = in();
	distsort(n, L, p);
	printf("%d\n", closest_pair(n, p));
	return 0;
}