时间限制:5.0s   内存限制:256.0MB  
总提交次数:547  
AC次数:137   平均分:40.31
将本题分享到:
      
试题来源
  2012中国国家集训队命题答辩
问题描述
  平面上有n个点。现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号。如果有两个(或多个)点距离(px, py)相同,那么认为标号较小的点距离较大。
输入格式
  第一行,一个整数n,表示点的个数。

  下面n行,每行两个整数x_i, y_i,表示n个点的坐标。点的标号按照输入顺序,分别为1..n。

  下面一行,一个整数m,表示询问个数。

  下面m行,每行三个整数px_i, py_i, k_i,表示一个询问。
输出格式
  m行,每行一个整数,表示相应的询问的答案。
样例输入
3

0 0

0 1

0 2

3

1 1 2

0 0 3

0 1 1
样例输出
3

1

1
数据规模和约定
  50%的数据中,n个点的坐标在某范围内随机分布。

  100%的数据中,n<=10^5, m<=10^4, 1<=k<=20,所有点(包括询问的点)的坐标满足绝对值<=10^9,n个点中任意两点坐标不同,m个询问的点的坐标在某范围内随机分布。

【题解】

kd-tree。

注意求的是第k“远"

在找到时候用一个队列维护当前找到的前k远的距离(因为k最大只有20,所以不用写恶心的二分检索了)。

即dl[1..k],其中dl[k]是第k远,dl[1]是最远的。

然后估价函数的判断变成

gujia[某个方向] >= dl[k]

满足则继续往那个方向找。

ma_x[2],mi_n[2]是某个子树的里面点的坐标最大可能形成的矩形的左上角和右上角坐标。

[0]是x,[1]是y;

【代码】

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int MAXN = 150000;
const int MAXK = 30;
struct point
{
long long d[2], ma_x[2], mi_n[2];
int l, r, id;
};
struct ddl
{
long long dis;
int id;
};
int n, root, now, k;
point t[MAXN], p[MAXN], op;
long long x[MAXN], y[MAXN];
ddl dl[MAXK];
bool cmp(point a, point b)
{
if (a.d[now] < b.d[now])
return true;
return false;
}
void push_up(int rt)
{
int l = t[rt].l, r = t[rt].r;
for (int i = 0; i <= 1; i++)
{
if (l)
{
t[rt].ma_x[i] = max(t[rt].ma_x[i], t[l].ma_x[i]);
t[rt].mi_n[i] = min(t[rt].mi_n[i], t[l].mi_n[i]);
}
if (r)
{
t[rt].ma_x[i] = max(t[rt].ma_x[i], t[r].ma_x[i]);
t[rt].mi_n[i] = min(t[rt].mi_n[i], t[r].mi_n[i]);
}
}
}
int build(int begin, int end, int fx)
{
int m = (begin + end) >> 1;
now = fx;
nth_element(p + begin, p + m, p + end + 1, cmp);//左闭右开区间
t[m] = p[m];
for (int i = 0; i <= 1; i++)
t[m].ma_x[i] = t[m].mi_n[i] = p[m].d[i];
if (begin < m)
t[m].l = build(begin, m - 1, 1 - fx);
if (m < end)
t[m].r = build(m + 1, end, 1 - fx);
push_up(m);
return m;
}
void input_data()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lld%lld", &x[i], &y[i]);
p[i].d[0] = x[i];
p[i].d[1] = y[i];
p[i].id = i;
}
root = build(1, n, 0);
}
long long get_dis(point a, point b)
{
return (a.d[0] - b.d[0])*(a.d[0] - b.d[0]) + (a.d[1] - b.d[1])*(a.d[1] - b.d[1]);
}
long long gujia_max(int rt)
{
long long temp = 0;
for (int i = 0; i <= 1; i++)
temp += max((t[rt].ma_x[i] - op.d[i])*(t[rt].ma_x[i] - op.d[i]), (t[rt].mi_n[i] - op.d[i])*(t[rt].mi_n[i] - op.d[i]));
return temp;
}
void query(int rt)
{
long long dis = get_dis(t[rt], op);
int tempk = k;
while (dl[tempk].dis < dis || (dl[tempk].dis == dis && t[rt].id < dl[tempk].id))
{
tempk--;
if (!tempk)
break;
}
if (tempk != k) //比第k远的大。就看看它是第几远。
{
for (int i = k; i >= tempk + 2; i--)
dl[i] = dl[i - 1];
dl[tempk + 1].dis = dis;
dl[tempk + 1].id = t[rt].id;
}
long long gl = -2, gr = -2;
int l = t[rt].l, r = t[rt].r;
if (l)
gl = gujia_max(l);
if (r)
gr = gujia_max(r);
if (gl < gr)
{
if (dl[k].dis <= gr) //注意估价函数的判断
query(r);
if (dl[k].dis <= gl)
query(l);
}
else
{
if (dl[k].dis <= gl)
query(l);
if (dl[k].dis <= gr)
query(r);
}
}
void output_ans()
{
int m;
scanf("%d", &m);
for (int i = 1; i <= m; i++)
{
memset(dl, 255, sizeof(dl));
scanf("%lld%lld%d", &op.d[0], &op.d[1], &k);
query(root);
printf("%d\n", dl[k].id);
}
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
output_ans();
return 0;
}

【24.91】【Tsinsen 1302】&【BZOJ 2626】JZPFAR的更多相关文章

  1. 【BZOJ 2749】 2749: [HAOI2012]外星人 (数论-线性筛?类积性函数)

    2749: [HAOI2012]外星人 Description Input Output 输出test行,每行一个整数,表示答案. Sample Input 1 2 2 2 3 1 Sample Ou ...

  2. 纳税服务系统【用户模块之使用POI导入excel、导出excel】

    前言 再次回到我们的用户模块上,我们发现还有两个功能没有完成: 对于将网页中的数据导入或导出到excel文件中,我们是完全没有学习过的.但是呢,在Java中操作excel是相对常用的,因此也有组件供我 ...

  3. C# 获取 mp3文件信息【包括:文件大小、歌曲长度、歌手、专辑】

    C# 获取 mp3文件信息[包括:文件大小.歌曲长度.歌手.专辑] 第一种方式:[代码已验证] // http://bbs.csdn.net/topics/390392612   string fil ...

  4. 【BZOJ 2194】2194: 快速傅立叶之二(FFT)

    2194: 快速傅立叶之二 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1273  Solved: 745 Description 请计算C[k]= ...

  5. 【BZOJ 4663】 (最小割)

    4663: Hack Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 69  Solved: 26 Description 由于 FZYZ 教学区禁止使 ...

  6. 【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引

    索引 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(1)搭建MVC环境 注册区域 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(2)创建 ...

  7. 【如何快速的开发一个完整的iOS直播app】(原理篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...

  8. 推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】

    最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽 ...

  9. 【MyEclipse 2015】 逆向破解实录系列【终】(纯研究)

    声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...

随机推荐

  1. css 兼容性前缀

    一.不同浏览器内核下的书写规则 二:transform  具体变性中心基点  transform-origin  默认情况下  rotate旋转.scale缩放.translate位移.矩阵matri ...

  2. HDU 1007 Quoit Design 平面内最近点对

    http://acm.hdu.edu.cn/showproblem.php?pid=1007 上半年在人人上看到过这个题,当时就知道用分治但是没有仔细想... 今年多校又出了这个...于是学习了一下平 ...

  3. 关于Promise详解

    异步回调 回调地狱 在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的回调地狱 并行结果 如果几个异步操作之间并没有前后顺序之分,但需要等多个异步操作都完成后才能执行后续的任务 ...

  4. 使用网络TCP搭建一个简单文件下载器

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 目录 一丶项目介绍 二丶服务器Server 三丶测试TCP server服务器 四丶客户端Client 五丶测试客户端向服务器下载 ...

  5. 邮件协议与port

          电子邮箱的协议有SMTP.POP2.POP3.IMAP4等.都隶属于TCP/IP协议簇,默认状态下.分别通过TCPport25.110和143建立连接.针对不同的用途和功能,我们在邮件se ...

  6. jquery ui 分页插件 传入后台的连个參数名

    參数名: page .rows page=int(request.form.get('page',1).encode('u8')) rows1=int(request.form.get('rows', ...

  7. 7,NULL与nullptr对比

    #include <iostream> #include <array> using namespace std; void show(int num) { cout < ...

  8. select into from 与 insert into select 区别

    1.INSERT INTO SELECT语句 语句形式为:Insert into Table2(field1,field2,...) select value1,value2,... from Tab ...

  9. (转) 如何取消Linux下,vi中显示的^M符号

    转自:http://www.cnblogs.com/dkblog/archive/2012/02/03/2337187.html [背景知识] ^M 是ascii中的'\r', 回车符,是16进制的0 ...

  10. 【Android开发经验】我们要友好的告诉用户,程序要崩溃了

        转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992     尽管我们的程序在正式上线之前,都会经过严格的測试.从而保证程序的健壮性和良好的用户体验,可是 ...