---
# System prepended metadata

title: closest pair
tags: [codebook]

---

---
tags: codebook
---

{%hackmd theme-dark %}

# closest pair


## STL

```cpp=
ll distance(const auto& a, const auto& b) {
	return (a.first - b.first) * (a.first - b.first)
	       + (a.second - b.second) * (a.second - b.second);
}
struct cmp {
	bool operator()(const pair<ll, ll>& a, const pair<ll, ll>& b) const {
		return a.second < b.second
		       || (a.second == b.second && a.first < b.first);
	}
};
long long closest_pair(vector<pair<ll, ll>>& v) {
	set<pair<ll, ll>, cmp> s;
	long long d = numeric_limits<long long>::max();
	for (size_t r = 0, l = 0; r != v.size(); r++) {
		while (l <= r && v[r].first - v[l].first > sqrt(d))
			s.erase(v[l++]);
		auto i = s.insert(v[r]).first, j = i;
		for (int k = 0; ++j != s.end() && k != 2; k++)
			d = min(d, distance(*i, *j));
		j = i;
		for (int k = 0; j-- != s.begin() && k != 2; k++)
			d = min(d, distance(*i, *j));
	}
	return d;
}
inline void solve() {
	int n; cin >> n;
	V<P<ll>> v(n);
	for (auto& [a, b] : v)
		cin >> a >> b;
	sort(v.begin(), v.end());
	cout << closest_pair(v) << endl;
}
```


## Recursive

```cpp=
inline ll d(P<ll> a, P<ll> b) {
	return (a.first - b.first) * (a.first - b.first)
	       + (a.second - b.second) * (a.second - b.second);
}
inline ll dx(P<ll> a, P<ll> b) {
	return (a.first - b.first) * (a.first - b.first);
}
ll closest_pair(const V<P<ll>>& v, int l, int r) {
	if (r - l < 2) return inf;
	int m = (l + r) >> 1;
	ll ret = min(closest_pair(v, l, m), closest_pair(v, m, r));
	V<P<ll>> tmp;
	for (int i = m; i < r && dx(v[i], v[m]) < ret; i++)
		tmp.emplace_back(v[i]);
	for (int i = m - 1; i >= l && dx(v[i], v[m]) < ret; i--)
		tmp.emplace_back(v[i]);
	sort(tmp.begin(), tmp.end(), [](auto a, auto b) {
		return a.second < b.second;
	});
	// debug(tmp);
	for (int i = 0; i < (int)tmp.size(); i++)
		for (int j = i + 1; j < min((int)tmp.size(), i + 4); j++)
			ret = min(ret, d(tmp[i], tmp[j]));
	// debug(l, r, ret);
	return ret;
}
inline void solve() {
	int n; cin >> n;
	V<P<ll>> v(n);
	for (auto& [a, b] : v)
		cin >> a >> b;
	sort(v.begin(), v.end());
	cout << closest_pair(v, 0, n) << endl;
}
```