BZOJ2458: [BeiJing2011]最小三角形
阿新 • • 發佈:2019-01-14
hup ret beijing line str lse con [1] urn
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); }
BZOJ2458: [BeiJing2011]最小三角形