原题链接


Palace

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 551    Accepted Submission(s): 186


Problem Description

The last trial Venus imposes on Psyche is a quest to the underworld. She is to take a box and obtain in it a dose of the beauty of Prosperina, queen of the underworld.
There are n palaces in the underworld, which can be located on a 2-Dimension plane with (x,y) coordinates (where x,y are integers). Psyche would like to find the distance of the closest pair of two palaces. It is the password to enter the main palace.
However, the underworld is mysterious and changes all the time. At different times, exactly one of the n palaces disappears. 
Psyche wonders what the distance of the closest pair of two palaces is after some palace has disappeared.
Print the sum of the distance after every single palace has disappeared. 
To avoid floating point error, define the distance d between palace (x1,y1) and (x2,y2) as d=(x1−x2)2+(y1−y2)2.

Input

The first line of the input contains an integer T (1≤T≤5), which denotes the number of testcases.
For each testcase, the first line contains an integers n (3≤n≤105), which denotes the number of temples in this testcase.
The following n lines contains n pairs of integers, the i-th pair (x,y) (−105≤x,y≤105) denotes the position of the i-th palace.


Output

For each testcase, print an integer which denotes the sum of the distance after every single palace has disappeared.


Sample Input

1 3 0 0 1 1 2 2


Sample Output

12

Hint

    这道题是经典的平面最接近点问题。先用分治找到最接近的两个点,求出它们的距离d, 设总共有n个点,那么答案ans += (n-2) * d.在分别去掉这两个点中的一个,求最接近点的距离,加到ans上。

If palace $ (0,0) $ disappears,$ d = (1-2) ^ 2 + (1 - 2) ^ 2 = 2 $;

If palace $ (1,1) $ disappears,$ d = (0-2) ^ 2 + (0 - 2) ^ 2 = 8 $;

If palace $ (2,2) $ disappears,$ d = (0-1) ^ 2 + (0-1) ^ 2 = 2 $;

Thus the answer is $ 2 + 8 + 2 = 12 $。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#define MOD 1000000007
#define maxn 100005
#define INF 1e16

using namespace std;
typedef long long ll;

struct Node{
	Node(){
	}
	Node(int a, int b){
		x = a;
		y = b;
	}
	friend bool operator < (const Node&a, const Node&b){
		return a.x < b.x;
	} 
	friend bool operator != (const Node &a, const Node&b){
		if(a.x != b.x || a.y != b.y)
		  return true;
		return false;
	}
	int x, y;
}k1[maxn], k2[maxn], k3[maxn], ans1, ans2;
ll mins;
ll f(Node &a, Node &b){
	return (ll)(a.x - b.x) * (a.x - b.x) + (ll)(a.y - b.y) * (a.y - b.y);
}
bool cmp(const Node &a, const Node &b){
	return a.y < b.y;
}
void solve(Node *k, int l, int r){
	
	if(r - l == 1){
	    ll d = f(k[l], k[r]);
	    if(d < mins){
	    	mins = d;
	    	ans1 = k[l];
	    	ans2 = k[r];
	    }
	    return ;
	}
	if(l == r){
	   return ;
	}
	int mid = (l + r) >> 1;
	solve(k, l, mid);
	solve(k, mid+1, r);
	vector<Node> p;
	for(int i = mid; i >= l; i--){
		if((ll)(k[i].x - k[mid].x) * (k[i].x - k[mid].x) < mins){
			p.push_back(k[i]);
		}
		else
		   break;
	}
	for(int i = mid+1; i <= r; i++){
		if((ll)(k[i].x - k[mid].x) * (k[i].x - k[mid].x) < mins){
			p.push_back(k[i]);
		}
		else
		 break;
	}
	sort(p.begin(), p.end(), cmp);
	for(int i = 0; i < p.size(); i++){
		for(int j = i+1; j < p.size() && (ll)(p[i].y - p[j].y) * (p[i].y - p[j].y) < mins; j++){
			ll kk = f(p[i], p[j]);
			if(kk < mins){
				mins = kk;
				ans1 = p[i];
				ans2 = p[j];   
			}		
		}
	}
}
int main(){
	
//	freopen("in.txt", "r", stdin);
	int t;
	
	scanf("%d", &t);
	while(t--){
		int n;
		ll h = 0;
		scanf("%d", &n);
		for(int i = 0; i < n; i++){
			scanf("%d%d", &k1[i].x, &k1[i].y);
		}
		sort(k1, k1+n);
		mins = INF;
        solve(k1, 0, n-1);
        h += (n - 2) * mins;
		Node d1 = ans1, d2 = ans2;
		int cnt = 0;
		int sign = 0;
		for(int i = 0; i < n; i++){
			if(k1[i] != d1 || sign){
			k2[cnt++] = k1[i];
		    }
		    else
		      sign = 1;
		}
		mins = INF;
		solve(k2, 0, n-2);
		h += mins;
		mins = INF;
		cnt = 0;
		sign = 0;
		for(int i = 0; i < n; i++){
			if(k1[i] != d2 || sign){
			  k3[cnt++] = k1[i];
		    }
		    else
		     sign = 1;
		}
		solve(k3, 0, n-2); 
		h += mins;
		printf("%I64d\n", h);
	} 
	return 0;
}