[BZOJ][KD-tree]2626: JZPFAR
来源:互联网 发布:python cuda编程 编辑:程序博客网 时间:2024/04/30 22:31
题目
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
3
0 0
0 1
0 2
3
1 1 2
0 0 3
0 1 1
Sample Output
3
1
1
数据规模和约定
50%的数据中,n个点的坐标在某范围内随机分布。
100%的数据中,n<=10^5, m<=10^4, 1<=k<=20,所有点(包括询问的点)的坐标满足绝对值<=10^9,n个点中任意两点坐标不同,m个询问的点的坐标在某范围内随机分布。
题解
又打了权限题,会不会没人看啊。
KD-tree+优先队列就可以A,因为只有2维,KD-tree还是比较好打的吧。然后就是正常的建树,查询。
代码
#include <cstdio>#include <queue>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;#define N 100000inline char tc(void){ static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;}inline int read(void){ int a=0,f=1;static char c; while((c=tc())<'0'||c>'9')c=='-'?f=-1:0; while(c>='0'&&c<='9')a=a*10+c-'0',c=tc(); return a*f;}inline int max(int a,int b){ return a>b?a:b;}inline int min(int a,int b){ return a<b?a:b;}int n,m,root,D,x,y,k,ans;double dis1,dis2;struct Y{ int d[2],mx[2],mix[2],l,r,h; inline bool operator <(const Y&a) const{ return d[D]<a.d[D]; }}a[N+2];struct M{ int h; double dis; inline bool operator <(const M&a) const{ return dis>a.dis||dis==a.dis&&h<a.h; }}o;priority_queue<M> s;void update(int k,int s){ a[k].mx[0]=max(a[k].mx[0],a[s].mx[0]), a[k].mx[1]=max(a[k].mx[1],a[s].mx[1]), a[k].mix[0]=min(a[k].mix[0],a[s].mix[0]), a[k].mix[1]=min(a[k].mix[1],a[s].mix[1]); return ;}int build(int l,int r,int dd){ int mid=l+r>>1;D=dd; nth_element(a+l+1,a+mid+1,a+r+1); a[mid].mix[0]=a[mid].mx[0]=a[mid].d[0], a[mid].mix[1]=a[mid].mx[1]=a[mid].d[1]; if(l!=mid) a[mid].l=build(l,mid-1,dd^1); else a[mid].l=0; if(r!=mid) a[mid].r=build(mid+1,r,dd^1); else a[mid].r=0; if(a[mid].l) update(mid,a[mid].l); if(a[mid].r) update(mid,a[mid].r); return mid;}double distance(int w){ double dis1=0; dis1+=max(double(x-a[w].mix[0])*(x-a[w].mix[0]),double(x-a[w].mx[0])*(x-a[w].mx[0])); dis1+=max(double(y-a[w].mix[1])*(y-a[w].mix[1]),double(y-a[w].mx[1])*(y-a[w].mx[1])); return dis1;}void query(int now,int dd){ double dis1,dis2; o.h=a[now].h,o.dis=1ll*(a[now].d[0]-x)*(a[now].d[0]-x)+1ll*(a[now].d[1]-y)*(a[now].d[1]-y),D=dd; if(s.size()<k) s.push(o); else if(o<s.top()) s.pop(),s.push(o); if(a[now].l)dis1=distance(a[now].l); else dis1=-1; if(a[now].r)dis2=distance(a[now].r); else dis2=-1; if(dis1>dis2){ if(dis1>=0&&(s.size()<k||dis1>=s.top().dis)) query(a[now].l,dd^1); if(dis2>=0&&(s.size()<k||dis2>=s.top().dis)) query(a[now].r,dd^1); } else{ if(dis2>=0&&(s.size()<k||dis2>=s.top().dis)) query(a[now].r,dd^1); if(dis1>=0&&(s.size()<k||dis1>=s.top().dis)) query(a[now].l,dd^1); } return ;}int main(void){ freopen("2626.in","r",stdin); freopen("2626.out","w",stdout); register int i; n=read(); for (i=1;i<=n;++i) a[i].d[0]=read(),a[i].d[1]=read(),a[i].h=i; root=build(1,n,0),m=read(); for (i=1;i<=m;++i){ x=read(),y=read(),k=read(),query(root,0); ans=s.top().h; while(!s.empty()) s.pop(); printf("%d\n",ans); } return 0;}
阅读全文
0 0
- [BZOJ][KD-tree]2626: JZPFAR
- [KD-TREE 堆] BZOJ 2626 JZPFAR
- bzoj 2626: JZPFAR (KD-tree)
- 【bzoj2626】JZPFAR kd-tree
- BZOJ 2626: JZPFAR|K-D tree
- [BZOJ2626]JZPFAR(kd-tree+堆)
- [BZOJ 2626]JZPFAR
- BZOJ 2626 JZPFAR
- 2626: JZPFAR K-D tree
- BZOJ 2626 JZPFAR K-D树
- 【24.91】【Tsinsen 1302】&【BZOJ 2626】JZPFAR
- [KD-TREE] BZOJ 4066 简单题
- [KD-TREE] BZOJ 2850 巧克力王国
- bzoj 2850: 巧克力王国 (KD-tree)
- bzoj 4066: 简单题 (KD-tree)
- bzoj 2683: 简单题 (KD-tree)
- [BZOJ]2648 SJY摆棋子 KD-Tree
- Bzoj2626:JZPFAR:K-D-Tree
- [leetcode] 43. Multiply Strings
- 激活函数和损失函数
- bzoj1767 树上dp斜率优化+二分
- java微信接收并回复文本信息(java微信开发学习笔记2)
- MySQL性能监控工具-MONyog
- [BZOJ][KD-tree]2626: JZPFAR
- react native 获取控件本身的高度
- hdu5412:CRB and Queries (整体二分+树状数组)
- 推挽输出、开漏输出、复用开漏输出、复用推挽输出 以及上拉输入、下拉输入、浮空输入、模拟输入的区别
- 微信公众号"发送一次性订阅消息"接口的使用
- 缺失值的处理
- Eclipse vs. IDEA快捷键对比大全
- Mysql学习随笔
- matlab实用源代码