[国家集训队2012]JZPFAR
[国家集训队2012]JZPFAR
题目
平面上有n个点。现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号。如果有两个(或多个)点距离(px, py)相同,那么认为标号较小的点距离较大。
INPUT
第一行,一个整数n,表示点的个数。
下面n行,每行两个整数x_i, y_i,表示n个点的坐标。点的标号按照输入顺序,分别为1..n。
下面一行,一个整数m,表示询问个数。
下面m行,每行三个整数px_i, py_i, k_i,表示一个询问。OUTPUT
m行,每行一个整数,表示相应的询问的答案。
SAMPLE
INPUT
3
0 0
0 1
0 2
3
1 1 2
0 0 3
0 1 1OUTPUT
3
1
1
解题报告
首道K-D树
然而只是照着打了个板子QAQ
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<queue> 6 using namespace std; 7 typedef long long L; 8 const L inf((L)1e16); 9 int now,n,m,k; 10 inline int read(){ 11 int sum(0),f(1); 12 char ch(getchar()); 13 for(;ch<'0'||ch>'9';ch=getchar()) 14 if(ch=='-') 15 f=-1; 16 for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar()); 17 return sum*f; 18 } 19 struct point{ 20 L a[3]; 21 inline bool operator<(const point &b)const{ 22 return a[now]<b.a[now]||(a[now]==b.a[now]&&a[now^1]<b.a[now^1]); 23 } 24 L &operator[](int x){ 25 return a[x]; 26 } 27 }p[100005],cmp; 28 struct data{ 29 L dis,id; 30 inline bool operator<(const data &a)const{ 31 return dis==a.dis?id<a.id:dis>a.dis; 32 } 33 }; 34 priority_queue<data>q; 35 inline L pf(L x){ 36 return x*x; 37 } 38 inline L dis(point x,point y){ 39 return pf(x[0]-y[0])+pf(x[1]-y[1]); 40 } 41 struct node{ 42 node *lch,*rch; 43 point key; 44 int mn[2],mx[2]; 45 node(point &x):key(x),lch(NULL),rch(NULL){ 46 mn[0]=mx[0]=x[0]; 47 mn[1]=mx[1]=x[1]; 48 } 49 inline void pushup(node *x){ 50 if(x==NULL) 51 return; 52 mn[0]=min(mn[0],x->mn[0]),mn[1]=min(mn[1],x->mn[1]); 53 mx[0]=max(mx[0],x->mx[0]),mx[1]=max(mx[1],x->mx[1]); 54 } 55 inline L cal_dis(){ 56 L ret(0); 57 ret=max(ret,dis((point){mn[0],mn[1]},cmp)); 58 ret=max(ret,dis((point){mn[0],mx[1]},cmp)); 59 ret=max(ret,dis((point){mx[0],mn[1]},cmp)); 60 ret=max(ret,dis((point){mx[0],mx[1]},cmp)); 61 return ret; 62 } 63 }*root; 64 inline void build(node *&rt,int l,int r,int d){ 65 if(l>r) 66 return; 67 int mid((l+r)>>1); 68 now=d; 69 nth_element(p+l,p+mid,p+r+1); 70 rt=new node(p[mid]); 71 build(rt->lch,l,mid-1,d^1); 72 build(rt->rch,mid+1,r,d^1); 73 rt->pushup(rt->lch); 74 rt->pushup(rt->rch); 75 } 76 inline void query(node *rt){ 77 if(rt==NULL) 78 return; 79 if(q.size()==k&&rt->cal_dis()<q.top().dis) 80 return; 81 data ret((data){dis(rt->key,cmp),rt->key[2]}); 82 if(q.size()<k) 83 q.push(ret); 84 else 85 if(ret<q.top()) 86 q.pop(),q.push(ret); 87 L dis_l(rt->lch==NULL?inf:rt->lch->cal_dis()); 88 L dis_r(rt->rch==NULL?inf:rt->rch->cal_dis()); 89 if(dis_l>dis_r){ 90 query(rt->lch); 91 if(dis_r>=q.top().dis||q.size()<k) 92 query(rt->rch); 93 } 94 else{ 95 query(rt->rch); 96 if(dis_l>=q.top().dis||q.size()<k) 97 query(rt->lch); 98 } 99 } 100 inline int gg(){ 101 freopen("jzpfar.in","r",stdin); 102 freopen("jzpfar.out","w",stdout); 103 n=read(); 104 for(int i=1;i<=n;++i) 105 p[i][0]=read(),p[i][1]=read(),p[i][2]=i; 106 build(root,1,n,0); 107 m=read(); 108 while(m--){ 109 cmp[0]=read(),cmp[1]=read(),k=read(); 110 while(!q.empty()) 111 q.pop(); 112 query(root); 113 printf("%d\n",q.top().id); 114 } 115 return 0; 116 } 117 int K(gg()); 118 int main(){;}