BZOJ2458: [BeiJing2011]最小三角形

BZOJ2458: [BeiJing2011]最小三角形

https://lydsy.com/JudgeOnline/problem.php?id=2458

分析:

  • 求最近点次近点更新答案能A掉这道题,虽然我不知道是不是正确的。
  • 那么用\(KDtree\)乱搞即可。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iostream>
using namespace std;
typedef long long ll;
typedef double f2;
#define N 200050
#define db(x) cerr<<#x<<" = "<<x<<endl
#define ls ch[p][0]
#define rs ch[p][1]
int now;
struct Point {
	ll p[2];
	Point() {p[0]=p[1]=0;}
	Point(ll x_,ll y_) {p[0]=x_,p[1]=y_;}
	bool operator < (const Point &u) const {
		return p[now]==u.p[now] ? p[!now] < u.p[!now] : p[now] < u.p[now];
	}
}a[N];
int n,ch[N][2],mx[N][2],mn[N][2],root;
void pushup(int p,int x) {
	mn[p][0]=min(mn[p][0],mn[x][0]);
	mn[p][1]=min(mn[p][1],mn[x][1]);
	mx[p][0]=max(mx[p][0],mx[x][0]);
	mx[p][1]=max(mx[p][1],mx[x][1]);
}
int build(int l,int r,int flg) {
	int mid=(l+r)>>1,p=mid;
	now=flg;
	nth_element(a+l,a+mid,a+r+1);
	mx[p][0]=mn[p][0]=a[p].p[0];
	mx[p][1]=mn[p][1]=a[p].p[1];
	if(l<mid) ls=build(l,mid-1,flg^1),pushup(p,ls);
	if(r>mid) rs=build(mid+1,r,flg^1),pushup(p,rs);
	return p;
}
int p1,p2;
ll s1,s2;
ll pf(ll x) {return x*x;}
ll calc(const Point &p1,const Point &p2) {return pf(p1.p[0]-p2.p[0])+pf(p1.p[1]-p2.p[1]);}
ll F(int x,int p) {
	if(a[p].p[0]>=mn[x][0]&&a[p].p[0]<=mx[x][0]&&a[p].p[1]>=mn[x][1]&&a[p].p[1]<=mx[x][1]) return 0;
	if(a[p].p[0]>=mn[x][0]&&a[p].p[0]<=mx[x][0]) {
		return min(pf(mn[x][1]-a[p].p[1]),pf(mx[x][1]-a[p].p[1]));
	}
	if(a[p].p[1]>=mn[x][1]&&a[p].p[1]<=mx[x][1]) {
		return min(pf(mn[x][0]-a[p].p[0]),pf(mx[x][0]-a[p].p[0]));
	}
	return min(calc(a[p],Point(mn[x][0],mn[x][1])),min(calc(a[p],Point(mn[x][0],mx[x][1])),min(calc(a[p],Point(mx[x][0],mn[x][1])),calc(a[p],Point(mx[x][0],mx[x][1])))));
}
void query(int p,int id) {
	ll t=calc(a[p],a[id]);
	if(p!=id&&(!p1||t<s1)) {
		s1=t; p1=p;
	}
	ll dls=ls?F(ls,id):1ll<<62;
	ll drs=rs?F(rs,id):1ll<<62;
	if(dls<drs) {
		if(dls<s1) query(ls,id);
		if(drs<s1) query(rs,id);
	}else {
		if(drs<s1) query(rs,id);
		if(dls<s1) query(ls,id);
	}
}
void query2(int p,int id) {
	ll t=calc(a[p],a[id]);
	if(p!=id&&p!=p1&&(!p2||t<s2)) {
		s2=t; p2=p;
	}
	ll dls=ls?F(ls,id):1ll<<62;
	ll drs=rs?F(rs,id):1ll<<62;
	if(dls<drs) {
		if(dls<s2) query2(ls,id);
		if(drs<s2) query2(rs,id);
	}else {
		if(drs<s2) query2(rs,id);
		if(dls<s2) query2(ls,id);
	}
}
int main() {
	scanf("%d",&n);
	int i;
	for(i=1;i<=n;i++) scanf("%lld%lld",&a[i].p[0],&a[i].p[1]);
	root=build(1,n,0);
	f2 ans=1e10;
	for(i=1;i<=n;i++) {
		p1=p2=0; s1=s2=1ll<<62;
		query(root,i);
		query2(root,i);
		ans=min(ans,sqrt(s1)+sqrt(s2)+sqrt(calc(a[p1],a[p2])));
	}
	printf("%.6f\n",ans);
}
posted @ 2019-01-13 21:26  fcwww  阅读(220)  评论(0编辑  收藏  举报