BZOJ 2626: JZPFAR
Description
求平面第\(k\)远的点,\(n\leqslant 10^5\)
Solution
KD-Tree.
用一个堆统计答案即可...
Code
/************************************************************** Problem: 2626 User: BeiYu Language: C++ Result: Accepted Time:16080 ms Memory:4824 kb ****************************************************************/ #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 100050; const int M = 2; const int K = 25; inline int in(int x=0,char s=getchar(),int v=1) { while(s>'9'||s<'0') v=s=='-'?-1:v,s=getchar(); while(s>='0'&&s<='9') x=x*10+s-'0',s=getchar();return x*v; } #define lc p[o].ch[0] #define rc p[o].ch[1] #define mid ((l+r)>>1) #define sqr(x) ((x)*(x)) namespace KDTree { struct Node { int id,mi[M],mx[M],d[M],ch[2]; Node() { id=ch[0]=ch[1]=0; for(int i=0;i<M;i++) mi[i]=mx[i]=d[i]=0; } }p[N]; int D,cp,rt,k;Node qp; int cmp(const Node &a,const Node &b) { return a.d[D]<b.d[D]; } LL dis2(Node a,Node b) { LL d=0; for(int i=0;i<M;i++) d+=sqr((LL)a.d[i]-b.d[i]); return d; } double dis(Node a,Node b) { return sqrt(dis2(a,b)); } void Update(int o) { for(int i=0;i<M;i++) p[o].mx[i]=p[o].mi[i]=p[o].d[i]; if(lc) for(int i=0;i<M;i++) p[o].mx[i]=max(p[o].mx[i],p[lc].mx[i]),p[o].mi[i]=min(p[o].mi[i],p[lc].mi[i]); if(rc) for(int i=0;i<M;i++) p[o].mx[i]=max(p[o].mx[i],p[rc].mx[i]),p[o].mi[i]=min(p[o].mi[i],p[rc].mi[i]); } void Build(int &o,int l,int r,int d) { D=d,o=mid,nth_element(p+l,p+o,p+r+1,cmp); if(l<mid) Build(lc,l,mid-1,(d+1)%M); if(r>mid) Build(rc,mid+1,r,(d+1)%M); Update(o); } LL S(int o) { LL res=0; for(int i=0;i<M;i++) res+=max(sqr((LL)p[o].mx[i]-qp.d[i]),sqr((LL)qp.d[i]-p[o].mi[i])); return res; } struct QNode { LL d2;int id; }; bool operator < (const QNode &a,const QNode &b) { return a.d2==b.d2?a.id<b.id:a.d2>b.d2; } priority_queue<QNode> q; void Query(int o) { if(!o) return; LL d=dis2(p[o],qp),ll=lc?S(lc):-2,rr=rc?S(rc):-2; if((QNode) { d,p[o].id } < q.top()) q.pop(),q.push((QNode) { d,p[o].id }); if(ll>rr) { if(ll>=q.top().d2) Query(lc); if(rr>=q.top().d2) Query(rc); } else { if(rr>=q.top().d2) Query(rc); if(ll>=q.top().d2) Query(lc); } } int Qur(int k,Node a) { for(;!q.empty();) q.pop(); for(int i=0;i<k;i++) q.push((QNode) { -1,0 }); qp=a; Query(rt); return q.top().id; } }; using namespace KDTree; int n,m; int main() { cp=n=in(); for(int i=1;i<=n;i++) { for(int j=0;j<M;j++) p[i].d[j]=in(); p[i].id=i; } Build(rt=1,1,n,0); for(m=in();m--;) { Node a=Node(); for(int j=0;j<M;j++) a.d[j]=in(); int k=in(); printf("%d\n",Qur(k,a)); } return 0; }