时间限制: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. 2.1 Producer API官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ 2.1 Producer API 2.1.生产者API 我们鼓励所有新开发的程序使用 ...

  2. POJ 1320 Street Numbers Pell方程

    http://poj.org/problem?id=1320 题意很简单,有序列 1,2,3...(a-1),a,(a+1)...b  要使以a为分界的 前缀和 和 后缀和 相等 求a,b 因为序列很 ...

  3. [CSS] Build a Fluid Loading Animation in CSS

    In this lesson, we will create a fluid loading animation using Animations and Transformations in CSS ...

  4. 25.Spring @Transactional工作原理

    转自:http://www.importnew.com/12300.html 本文将深入研究Spring的事务管理.主要介绍@Transactional在底层是如何工作的.之后的文章将介绍: prop ...

  5. Python编写Appium测试用例(2)

    #coding=utf-8import os,sysimport unittestfrom appium import webdriverimport timefrom selenium.webdri ...

  6. 软件——python,主函数

    1;; 如何在spyder中运行python程序 如下图,   写入一个输出  ' hellow word '的程序 然后点击运行按钮就可以运行了.

  7. 小程序踩坑记- tabBar.list[3].selectedIconPath 大小超过 40kb

    重新启动微信小程序编辑器的时候遇到了这样的一个问题: tabBar.list[3].selectedIconPath 大小超过 40kb 微信小程序开发的过程之中总会出现这样或者那样的错误,需要我们耐 ...

  8. Java基础学习总结(50)——Java事务处理总结

    一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ...

  9. 关于LWIP断开网线后重连问题(热插拔问题)

    近期在弄STM32+LWIP协议.在网络拔掉网线情况下.无法又一次连接. 网上找了好多方法都没有实现,着实郁闷! 后来无意间看到了临时解决这一问题的方法.尽管不是那么完美,但最算能解决这个问题.分享给 ...

  10. Seal Report开放数据库报表工具(.Net)

    Seal Report_20160923 概述:开放数据库报表工具(.Net) 简介:Seal-Report提供了一个完整的框架,用于从任何数据库生成日常报告和仪表板.Seal-Report是Micr ...