Problem Description

There are N hotels all over the world. Each hotel has a location and a price. M guests want to find a hotel with an acceptable price and a minimum distance from their locations. The distances are measured in Euclidean metric.

Input

The first line is the number of test cases. For each test case, the first line contains two integers N (N ≤ 200000) and M (M ≤ 20000). Each of the following N lines describes a hotel with 3 integers x (1 ≤ x ≤ N), y (1 ≤ y ≤ N) and c (1 ≤ c ≤ N), in which x and y are the coordinates of the hotel, c is its price. It is guaranteed that each of the N hotels has distinct x, distinct y, and distinct c. Then each of the following M lines describes the query of a guest with 3 integers x (1 ≤ x ≤ N), y (1 ≤ y ≤ N) and c (1 ≤ c ≤ N), in which x and y are the coordinates of the guest, c is the maximum acceptable price of the guest.

Output

For each guests query, output the hotel that the price is acceptable and is nearest to the guests location. If there are multiple hotels with acceptable prices and minimum distances, output the first one.

Sample Input

2

3 3

1 1 1

3 2 3

2 3 2

2 2 1

2 2 2

2 2 3

5 5

1 4 4

2 1 2

4 5 3

5 2 1

3 3 5

3 3 1

3 3 2

3 3 3

3 3 4

3 3 5

Sample Output

1 1 1

2 3 2

3 2 3

5 2 1

2 1 2

2 1 2

1 4 4

3 3 5

Source

2016ACM/ICPC亚洲区青岛站-重现赛(感谢中国石油大学)

【题目链接】:http://acm.split.hdu.edu.cn/showproblem.php?pid=5992

【题解】



先炫耀一下;



kd-tree;

如果没学过kd-tree不建议你再往下看。

这里不能用那个四边形的估价函数;会超时。

有一个更好的估价函数是

judge=(op.d[fx]-t[rt].d[fx])^2;

op是输入的询问,d[2]表示坐标;(二维)

这里的fx是kd-tree中当前这个域的划分依据,fx==0表示是以x轴作为划分依据、fx==1表示是以y轴作为划分依据;

具体点

    int zuo = t[rt].l,you = t[rt].r;
if (op.d[fx]>t[rt].d[fx])//先搞fx维坐标离操作坐标近的;
swap(zuo,you);
query(zuo,1-fx);//优先搞"左"子树
bool should = false;//判断要不要搞右子树;
if (dis == INF)//如果距离为正无穷表示还没有更新过答案就要搞
should = true;
else
{
LL ju = sqr(op.d[fx]-t[rt].d[fx]);//否则看看这个划分依据fx的维当前这个fx坐标与操作坐标的距离的平方
//经过了swap "you"子树内全部都是比t[rt].d[fx]小或全都比它大的节点;
if (ju <= dis)//如果估价函数比当前更新到的答案小;那么就要搞右子树
should = true;//如果估价函数比当前更新到的答案还要大,那么就不要搞右子树了;
}//因为如果继续搞右子树,fx这一维的坐标在右子树里面是单调的;ju只会越来越大;
if (should)
query(you,1-fx);

除此之外;还可以在每个树的节点里面储存以这个节点为根的子树下面最低消费最小的min;如果min都大于op.n则可以不用进入子树了;

(交程序的时候选g++不然会莫名TLE);



【完整代码】

#include <cstdio>
#include <algorithm>
#define LL long long using namespace std; const int MAXN = 205000;
const LL INF = 1e18; struct point
{
int min, n, dot, l,r;
LL d[2];
}; int n, m, root, now;
LL dis; point t[MAXN];
point op,ans; void input_data()
{
scanf("%d%d", &n,&m);
for (int i = 1; i <= n; i++)
{
scanf("%I64d%I64d%d", &t[i].d[0], &t[i].d[1],&t[i].n);
t[i].dot = i;
}
} bool cmp_1(point a, point b)
{
return a.d[now] < b.d[now];
} void gengxin(int father, int son)
{
if (t[father].min > t[son].min)
t[father].min = t[son].min;
} void up_data(int rt)
{
t[rt].min = t[rt].n;
int l = t[rt].l, r = t[rt].r;
if (l) gengxin(rt, l);
if (r) gengxin(rt, r);
} int build(int begin, int end, int fa,int fx)
{
int m = (begin + end) >> 1;
now = fx;
nth_element(t + begin, t + m, t + end + 1, cmp_1);
if (begin < m)
t[m].l = build(begin, m - 1, m, 1 - fx);
else
t[m].l = 0;
if (m < end)
t[m].r = build(m + 1, end, m, 1 - fx);
else
t[m].r = 0;
up_data(m);
return m;
} LL sqr(LL x)
{
return x*x;
} void query(int rt,int fx)
{
if (!rt)
return;
int temp1 = t[rt].min;
if (temp1 > op.n)
return;
if (t[rt].n <= op.n)
{
LL dd = sqr(op.d[0]-t[rt].d[0])+sqr(op.d[1]-t[rt].d[1]);
if (dd < dis || (dd==dis && t[rt].dot < ans.dot))
{
dis = dd;
ans.d[0] = t[rt].d[0];
ans.d[1] = t[rt].d[1];
ans.n = t[rt].n;
ans.dot = t[rt].dot;
}
}
int zuo = t[rt].l,you = t[rt].r;
if (op.d[fx]>t[rt].d[fx])
swap(zuo,you);
query(zuo,1-fx);
bool should = false;
if (dis == INF)
should = true;
else
{
LL ju = sqr(op.d[fx]-t[rt].d[fx]);
if (ju <= dis)
should = true;
}
if (should)
query(you,1-fx);
} void get_ans()
{
root = build(1, n, 0, 0);
for (int i = 1; i <= m; i++)
{
scanf("%I64d%I64d%d",&op.d[0],&op.d[1],&op.n);
dis = INF;
query(root,0);
printf("%I64d %I64d %d\n",ans.d[0],ans.d[1],ans.n);
}
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--)
{
input_data();
get_ans();
}
return 0;
}

【22.95%】【hdu 5992】Finding Hotels的更多相关文章

  1. 【改革春风吹满地 HDU - 2036 】【计算几何-----利用叉积计算多边形的面积】

    利用叉积计算多边形的面积 我们都知道计算三角形的面积时可以用两个邻边对应向量积(叉积)的绝对值的一半表示,那么同样,对于多边形,我们可以以多边形上的一个点为源点,作过该点并且过多边形其他点中的某一个的 ...

  2. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  3. Least Common Multiple (HDU - 1019) 【简单数论】【LCM】【欧几里得辗转相除法】

    Least Common Multiple (HDU - 1019) [简单数论][LCM][欧几里得辗转相除法] 标签: 入门讲座题解 数论 题目描述 The least common multip ...

  4. 七夕节 (HDU - 1215) 【简单数论】【找因数】

    七夕节 (HDU - 1215) [简单数论][找因数] 标签: 入门讲座题解 数论 题目描述 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们 ...

  5. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  6. 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...

  7. 【贪心】【模拟】HDU 5491 The Next (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5491 题目大意: 一个数D(0<=D<231),求比D大的第一个满足:二进制下1个个数在 ...

  8. 【动态规划】【二分】【最长上升子序列】HDU 5773 The All-purpose Zero

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5773 题目大意: T组数据,n个数(n<=100000),求最长上升子序列长度(0可以替代任何 ...

  9. 【动态规划】【KMP】HDU 5763 Another Meaning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...

随机推荐

  1. IBM磁盘阵列及文件系统的管理

    一.几个基本概念 物理卷(PV):一个物理卷指一块硬盘 卷组(VG):卷组是可用物理硬盘的集合,可以逻辑地看成一块大硬盘 物理分区(PP):卷组中物理卷划分成固定大小的块(缺省为4MB) 逻辑卷(LV ...

  2. Linux-swap分区

    Linux内核为了提高读写效率与速度,会将文件在内存中进行缓存,这部分内存就是Cache Memory(缓存内存).即使你的程序运行结束后, Cache Memory也不会自动释放.这就会导致你在Li ...

  3. 洛谷 P2392 kkksc03考前临时抱佛脚

    P2392 kkksc03考前临时抱佛脚 题目背景 kkksc03的大学生活非常的颓废,平时根本不学习.但是,临近期末考试,他必须要开始抱佛脚,以求不挂科. 题目描述 这次期末考试,kkksc03需要 ...

  4. Chrome不能在网易网盘中上传文件的解决办法

    Chrome不能在网易网盘中上传文件的解决办法1. 安装 Adobe Flash Player PPAPI,设置flash插件 chrome://settings/content/flash,许可[* ...

  5. 10小时之内,暴力破解SSH账号的IP

    10小时之内,暴力破解SSH账号的IP,IP 地址数据来源于  ip138.com 182.18.76.246 北京市昌平区 北京亿安天下网络科技有限公司 联通 221.223.200.143 北京市 ...

  6. 7lession-基础数据使用介绍

    1.数值 这个使用比较简单 a = 1 b = 3.2 c = 12.5+4j d = 20L 2.字符串 代码 s = "hello world,i am comming" pr ...

  7. [原创]react-vio-form 快速构建React表单应用

    react-vio-form 是一个react的快速轻量表单库,能快速实现表单构建.提供自定义表单格式.表单校验.表单信息反馈.表单信息隔离等功能.可采用组件声明或者API的形式来实现表单的功能 de ...

  8. 二、Docker基础操作

    原文:二.Docker基础操作 一.下载镜像 命令:docker pull xxxxxx(镜像名) docker pull training/weapp 二.运行镜像 docker run -d -P ...

  9. 【Codeforces Round #452 (Div. 2) A】 Splitting in Teams

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 贪心 1优先和2组队. 如果1没有了 就结束. 如果1还有多余的. 那么就自己3个3个组队 [代码] #include <bi ...

  10. 【Codeforces Round #451 (Div. 2) D】Alarm Clock

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 尺取法+二分. 类似滑动窗口. 即左端点为l,右端点为r. 维护a[r]-a[l]+1总是小于等于m的就好. (大于m就右移左端点) ...