[国家集训队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 1

OUTPUT

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
",q.top().id);
114     }
115     return 0;
116 }
117 int K(gg());
118 int main(){;}
View Code
原文地址:https://www.cnblogs.com/hzoi-mafia/p/7611744.html