BZOJ 2626 JZPFAR(KD-tree)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2626
题意:平面上有n个点。现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号。如果有两个(或多个)点距离(px, py)相同,那么认为标号较小的点距离较大。
思路:对n个点做KDtree。
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define ll long long
struct Point{
ll d[],max[],min[];
int l,r,id;
}a[];
int root,n,K,cmpd,id[],m;
ll X,Y,ans[];
bool cmp(Point p1,Point p2){
if (p1.d[cmpd]!=p2.d[cmpd]) return p1.d[cmpd]<p2.d[cmpd];
else return p1.d[!cmpd]<p2.d[!cmpd];
}
void updata(int x){
if (a[x].l){
int j=a[x].l;
for (int i=;i<;i++)
a[x].max[i]=std::max(a[x].max[i],a[j].max[i]),
a[x].min[i]=std::min(a[x].min[i],a[j].min[i]);
}
if (a[x].r){
int j=a[x].r;
for (int i=;i<;i++)
a[x].max[i]=std::max(a[x].max[i],a[j].max[i]),
a[x].min[i]=std::min(a[x].min[i],a[j].min[i]);
}
}
ll sqr(ll x){
return x*x;
}
ll dist(int p,ll x,ll y){
ll dis=,d1,d2;
d1=std::abs(x-a[p].max[]);
d2=std::abs(x-a[p].min[]);
if (d1>d2) dis+=d1*d1;
else dis+=d2*d2;
d1=std::abs(y-a[p].max[]);
d2=std::abs(y-a[p].min[]);
if (d1>d2) dis+=d1*d1;
else dis+=d2*d2;
return dis;
}
void query(int p){
if (!p) return;
ll dl,dr,d0;
int t=K;
d0=sqr(std::abs(a[p].d[]-X))+sqr(std::abs(a[p].d[]-Y));
while (t&&(d0>ans[t]||(d0==ans[t]&&a[p].id<id[t]))) t--;
if (t!=K){
t++;
for (int i=K;i>=t+;i--){
ans[i]=ans[i-];
id[i]=id[i-];
}
ans[t]=d0;id[t]=a[p].id;
}
if (a[p].l) dl=dist(a[p].l,X,Y);else dl=;
if (a[p].r) dr=dist(a[p].r,X,Y);else dr=;
if (dl>dr){
if (dl>=ans[K]) query(a[p].l);
if (dr>=ans[K]) query(a[p].r);
}else{
if (dr>=ans[K]) query(a[p].r);
if (dl>=ans[K]) query(a[p].l);
}
}
int build(int l,int r,int d){
int mid=(l+r)/;
cmpd=d;
std::nth_element(a+l,a+mid,a++r,cmp);
a[mid].max[]=a[mid].min[]=a[mid].d[];
a[mid].max[]=a[mid].min[]=a[mid].d[];
if (l!=mid) a[mid].l=build(l,mid-,!d);
if (r!=mid) a[mid].r=build(mid+,r,!d);
updata(mid);
return mid;
}
int main(){
scanf("%d",&n);
for (int i=;i<=n;i++){
scanf("%lld%lld",&a[i].d[],&a[i].d[]);
a[i].id=i;
}
root=build(,n,);
scanf("%d",&m);
while (m--){
scanf("%lld%lld%d",&X,&Y,&K);
for (int i=;i<=;i++) id[i]=,ans[i]=;
query(root);
printf("%d\n",id[K]);
}
}
BZOJ 2626 JZPFAR(KD-tree)的更多相关文章
- 简单题(K-D Tree)
简单题不简单-- 我们把单点加操作改成插入一个权值为增加量的点,将问题转化成询问一个矩阵中所有点的和,用 \(K-D\ Tree\) 维护,时间复杂度 \(O(n\sqrt{n})\) \(Code\ ...
- BZOJ 2648 SJY摆棋子(KD Tree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...
- 【BZOJ2843】极地旅行社(Link-Cut Tree)
[BZOJ2843]极地旅行社(Link-Cut Tree) 题面 BZOJ 题解 \(LCT\)模板题呀 没什么好说的了.. #include<iostream> #include< ...
- 【BZOJ1969】航线规划(Link-Cut Tree)
[BZOJ1969]航线规划(Link-Cut Tree) 题面 BZOJ 题解 删边操作 套路呀 离线读入倒过来做 变成加边操作 现在考虑怎么确定两点直接的关键路径条数 如果是一棵树,那么每条边都是 ...
- 【BZOJ3282】Tree (Link-Cut Tree)
[BZOJ3282]Tree (Link-Cut Tree) 题面 BZOJ权限题呀,良心luogu上有 题解 Link-Cut Tree班子提 最近因为NOIP考炸了 学科也炸了 时间显然没有 以后 ...
- 【BZOJ3999】[TJOI2015]旅游(Link-Cut Tree)
[BZOJ3999][TJOI2015]旅游(Link-Cut Tree) 题面 BZOJ 洛谷 题解 一道不难的\(LCT\)题(用树链剖分不是为难自己吗,这种有方向的东西用\(LCT\)不是方便那 ...
- 【BZOJ5212】[ZJOI2018]历史(Link-Cut Tree)
[BZOJ5212][ZJOI2018]历史(Link-Cut Tree) 题面 洛谷 BZOJ 题解 显然实际上就是给定了一棵树和每个点被\(access\)的次数,求解轻重链切换的最大次数. 先考 ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- 哈夫曼树(Huffman Tree)与哈夫曼编码
哈夫曼树(Huffman Tree)与哈夫曼编码(Huffman coding)
随机推荐
- altium designer Summer09出现的问题解决方案
在编译原理图时,引脚和连线旁边出现很多红线,提示 error:signal with no driver. 原理图没有加入到Project里. 第一次导入没问题,但是改了个元件的封装,在更新一下(De ...
- 关于iostream的效率问题
前言 经常有人说iostream的速度慢,IO流比stdio的慢多了.但是有人测试过的,iostream的速度是超过stdio的. 测试结果 /* C */#include <stdio. ...
- Linux Top使用说明
运行top后,按P键就按CPU排序,按M键就按内存排序 P – 以 CPU 占用率大小的顺序排列进程列表 M – 以内存占用率大小的顺序排列进程列表 在系统维护的过程中,随时可能有需要查看 CPU 使 ...
- cf494A Treasure
A. Treasure time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- Codeforce 217 div2
C 假设每种颜色的个数都相同,可以用轮换的方式,让答案达到最大n,当不同的时候,可以每次从每种颜色中取出相同个数的手套来操作; 一直迭代下去直到只剩下1种颜色; 再将这一种颜色与之前交换过的交换就行了 ...
- LeetCode 191. Number of 1 Bits Question
题意:给你一个整数,计算该整数的二进制形式里有多少个“1”.比如6(110),就有2个“1”. 一开始我就把数字n不断右移,然后判定最右位是否为1,是就cnt++,否则就继续右移直到n为0. 可是题目 ...
- java基础 二分查找算法
/* * 折半查找法: * 思路: * 定义三个变量记录查找范围中最大.最小和中间的索引值,每次都是使用中间索引值与要查找的目标进行对比,如果不符合,那么就不停缩小查找范围 * */ ...
- 3DShader之移位贴图(Displacement Mapping)
我们知道法线贴图是只是改了物体的法线属性,用来计算光照,但是并没有改变物体本身的网格.但是移位贴图就不一样了,它会移动物体的顶点.我用移位贴图做了个海洋,好了,上了图再讲: 注意看海的边缘的顶点,已经 ...
- Android自定义控件(三)——有弹性的ListView
上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性的ScrollView. 国际惯例,效果图: 主要代码: import android.content.Context; i ...
- 线程、线程句柄、线程ID
什么是句柄:句柄是一种指向指针的指针.我们知道,所谓指针是一种内存地址.应用程序启动后,组成这个程序的各对象是住留在内存的.如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 ...