bzoj4520 Cqoi2016—K远点对
Posted MashiroSky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4520 Cqoi2016—K远点对相关的知识,希望对你有一定的参考价值。
http://www.lydsy.com/JudgeOnline/problem.php?id=4520 (题目链接)
题意
求平面内第K远点对的距离。
Solution
左转题解:jump
细节
刚开始我还开了两个堆,想想其实是没必要的→_→
距离什么的开LL
代码
// bzoj4520 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<vector> #include<cmath> #include<queue> #define LL long long #define inf 1<<30 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=100010; int n,m,D,K,rt; priority_queue<LL,vector<LL>,greater<LL> > q; struct KDtree { int l,r,v[2],mn[2],mx[2]; friend bool operator < (const KDtree a,const KDtree b) { return a.v[D]<b.v[D]; } }tr[maxn],S; void update(int k) { for (int i=0;i<=1;i++) { if (tr[k].l) { tr[k].mn[i]=min(tr[k].mn[i],tr[tr[k].l].mn[i]); tr[k].mx[i]=max(tr[k].mx[i],tr[tr[k].l].mx[i]); } if (tr[k].r) { tr[k].mn[i]=min(tr[k].mn[i],tr[tr[k].r].mn[i]); tr[k].mx[i]=max(tr[k].mx[i],tr[tr[k].r].mx[i]); } } } int build(int l,int r,int p) { D=p; int mid=(l+r)>>1; nth_element(tr+l,tr+mid,tr+r+1); if (l<mid) tr[mid].l=build(l,mid-1,p^1); if (r>mid) tr[mid].r=build(mid+1,r,p^1); update(mid); return mid; } LL dis(LL x1,LL y1,LL x2,LL y2) { return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } LL eva(int k) { LL lu=dis(S.v[0],S.v[1],tr[k].mn[0],tr[k].mn[1]); LL ru=dis(S.v[0],S.v[1],tr[k].mx[0],tr[k].mn[1]); LL ld=dis(S.v[0],S.v[1],tr[k].mn[0],tr[k].mx[1]); LL rd=dis(S.v[0],S.v[1],tr[k].mx[0],tr[k].mx[1]); return max(max(lu,ru),max(ld,rd)); } void query(int k) { if (!k) return; LL d=dis(S.v[0],S.v[1],tr[k].v[0],tr[k].v[1]); if (q.top()<d) q.pop(),q.push(d); LL dl=eva(tr[k].l),dr=eva(tr[k].r); if (dl>dr) { if (q.top()<dl) query(tr[k].l); if (q.top()<dr) query(tr[k].r); } else { if (q.top()<dr) query(tr[k].r); if (q.top()<dl) query(tr[k].l); } } int main() { scanf("%d%d",&n,&K); for (int i=1;i<=n;i++) { scanf("%d%d",&tr[i].v[0],&tr[i].v[1]); tr[i].mn[0]=tr[i].mx[0]=tr[i].v[0]; tr[i].mn[1]=tr[i].mx[1]=tr[i].v[1]; } rt=build(1,n,0); for (int i=1;i<=2*K;i++) q.push(0); for (int i=1;i<=n;i++) S=tr[i],query(rt); printf("%lld",q.top()); return 0; }
以上是关于bzoj4520 Cqoi2016—K远点对的主要内容,如果未能解决你的问题,请参考以下文章