萌新刚学KD树,96pts wa tle都有,求问哪错了
查看原帖
萌新刚学KD树,96pts wa tle都有,求问哪错了
821939
zhi_hui_kan_ti_jie楼主2023/7/28 16:31
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define double long long
const int maxn = 1e6 + 10;
#define lc t[p].l
#define rc t[p].r
int n, K, root, cur;
struct KD{
	int l, r; //左右孩子
	double v[2]; //点的坐标值
	double L[2], U[2]; //子树区域坐标范围 
	bool operator<(const KD& b)const
	{	return v[K] < b.v[K];	}
}t[maxn];

inline void push_up(int p){
	for (int i = 0; i < 2; i++){
		t[p].L[i] = t[p].U[i] = t[p].v[i];
		if (lc)
			t[p].L[i] = min(t[p].L[i], t[lc].L[i]),
			t[p].U[i] = max(t[p].U[i], t[rc].U[i]);
		if (rc)
			t[p].L[i] = min(t[p].L[i], t[rc].L[i]),
			t[p].U[i] = max(t[p].U[i], t[rc].U[i]);
	}
}
int build(int l, int r, int k){
	if (l > r)return 0;
	int m = l + r >> 1;
	K = k; nth_element(t + l, t + m, t + r + 1);//中位数
	t[m].l = build(l, m - 1, k ^ 1);
	t[m].r = build(m + 1, r, k ^ 1);
	push_up(m);
	return m;
}
inline double sq(double x){ return x*x; }
double dis(int p){
	double s = 0;
	for (int i = 0; i < 2; i++)
		s += sq(t[cur].v[i] - t[p].v[i]);
	return s;
}
double dis2(int p){
	if (!p)return 2e18;
	double s = 0;
	for (int i = 0; i < 2; i++)
		s += sq(max(t[cur].v[i] - t[p].U[i], 0ll)) + sq(max(t[p].L[i] - t[cur].v[i], 0ll));
	return s;
}
double ans=2e18;
void query(int p){
	if (!p)return;
	if (p != cur)ans = min(ans, dis(p));
	double dl = dis2(lc), dr = dis2(rc);
	if (dl < dr){
		if (dl < ans)query(lc);
		if (dr < ans)query(rc);
	}
	else{
		if (dr < ans)query(rc);
		if (dl < ans)query(lc);
	}
}
signed main()
{
	/*ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);*/
	int n; cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> t[i].v[0] >> t[i].v[1];
	root = build(1, n, 0);
	for (cur = 1; cur <= n; cur++)query(root);
	cout<<(int)ans;
	return 0;
}
2023/7/28 16:31
加载中...