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;
}