BZOJ 2626 JZPFAR
2017-08-07 21:14
295 查看
Description
平面上有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
30 0
0 1
0 2
3
1 1 2
0 0 3
0 1 1
Sample Output
31
1
直接k-d树上按照找k近邻的方法找k远离即可...
#include <stdio.h> #include <cstring> #include <iostream> #include <queue> #include <algorithm> using std::max; using std::min; typedef long long ll; const ll inf = (ll)1e16; const int MAXN = 100005; int now,n,m,k; template<typename _t> inline _t read(){ _t x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-f; for(;isdigit(ch);ch=getchar())x=x*10+(ch^48); return x*f; } struct Point{ ll a[3]; inline bool operator < (const Point & b)const{ return a[now]<b.a[now]||(a[now]==b.a[now]&&a[now^1]<b.a[now^1]); } ll &operator [](int x){return a[x];} }pt[MAXN],cmp; struct res{ ll dis,id; bool operator < (const res & a)const{ return dis == a.dis? id < a.id : dis > a.dis; } }; std::priority_queue<res>Q; inline ll sqr(ll x){return x*x;} inline ll dis(Point x,Point y){return sqr(x[0]-y[0])+sqr(x[1]-y[1]);} struct node{ node *ls,*rs; Point point; int mn[2],mx[2]; node(Point &x){ point = x; ls = rs = NULL; mn[0]=mx[0]=x[0]; mn[1]=mx[1]=x[1]; } inline void Maintain(node *x){ if(x==NULL)return; for(int i=0;i<=1;i++)mn[i]=min(mn[i],x->mn[i]); for(int i=0;i<=1;i++)mx[i]=max(mx[i],x->mx[i]); } inline ll calc_dis(){ ll Ans = 0; Ans = max(Ans,dis((Point){mn[0],mn[1]},cmp)); Ans = max(Ans,dis((Point){mn[0],mx[1]},cmp)); Ans = max(Ans,dis((Point){mx[0],mn[1]},cmp)); Ans = max(Ans,dis((Point){mx[0],mx[1]},cmp)); return Ans; } }*root; void build(node *&o,int l,int r,int d){ if(l>r)return; int mid = l+r>>1; now = d;std::nth_element(&pt[l],&pt[mid],&pt[r+1]); o = new node(pt[mid]); build(o->ls,l,mid-1,d^1); build(o->rs,mid+1,r,d^1); o->Maintain(o->ls); o->Maintain(o->rs); } inline void Query(node *rt){ if(rt==NULL)return; if(Q.size()==k&&rt->calc_dis()<Q.top().dis)return; res ans = (res){dis(rt->point,cmp),rt->point[2]}; if(Q.size()<k)Q.push(ans); else if(ans<Q.top())Q.pop(),Q.push(ans);//这个东西重载了QAQ。。 ll dis_ls = rt->ls==NULL?inf:rt->ls->calc_dis(); ll dis_rs = rt->rs==NULL?inf:rt->rs->calc_dis(); if(dis_ls>dis_rs){ Query(rt->ls); if(dis_rs>=Q.top().dis||Q.size()<k)Query(rt->rs); } else{ Query(rt->rs); if(dis_ls>=Q.top().dis||Q.size()<k)Query(rt->ls); } } int main(){ n=read<int>(); for(int i=1;i<=n;++i)pt[i][0]=read<int>(),pt[i][1]=read<int>(),pt[i][2]=i; build(root,1,n,0); m=read<int>(); for(int i=1;i<=m;++i){ cmp[0]=read<int>();cmp[1]=read<int>(); k=read<int>(); while(!Q.empty())Q.pop(); Query(root); printf("%d\n",Q.top().id); } }
相关文章推荐
- BZOJ2626: JZPFAR
- [BZOJ 2626]JZPFAR
- 【bzoj2626】JZPFAR
- [BZOJ2626][清橙A1302]JZPFAR-K-D树
- [KD-TREE 堆] BZOJ 2626 JZPFAR
- 【24.91】【Tsinsen 1302】&【BZOJ 2626】JZPFAR
- Bzoj2626:JZPFAR:K-D-Tree
- [BZOJ][KD-tree]2626: JZPFAR
- BZOJ 2626 JZPFAR(KD-tree)
- [BZOJ2626]JZPFAR(kd-tree+堆)
- bzoj2626 JZPFAR(求K远点)
- BZOJ 2626 JZPFAR(KD-tree)
- 【BZOJ】【2626】JZPFAR
- bzoj2626 JZPFAR
- 【堆】【kd-tree】bzoj2626 JZPFAR
- 【bzoj2626】JZPFAR kd-tree
- 【bzoj2626】JZPFAR KD-tree+堆
- BZOJ 2626: JZPFAR|K-D tree
- bzoj 2626: JZPFAR (KD-tree)
- bzoj 2626: JZPFAR k-D树