用堆记录答案。看看当前点是否比堆顶更优。

#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef double db;
#define N 100001
#define EPS 0.0000001
#define INF 999999999999999999.0
#define KD 2//ά¶ÈÊý
int qp[KD];
int n,root,kd=2,K;
int dn;
struct Ans
{
int p[KD],id;
db d;
Ans(){}
Ans(int _p[],int _id,db _d){memcpy(p,_p,sizeof(p)); id=_id; d=_d;}
};
bool operator < (const Ans &a,const Ans &b)
{return fabs(a.d-b.d)>=EPS ? a.d>b.d : a.id<b.id;}
priority_queue<Ans>Heap;
db sqr(const int &x){return (db)x*(db)x;}
struct Node
{
int minn[KD],maxx[KD],p[KD],id;
int ch[2];
void Init()
{
for(int i=0;i<kd;++i)
minn[i]=maxx[i]=p[i];
}
db Dis()
{
db t=0;
for(int i=0;i<kd;++i)
{
t+=sqr(max(0,qp[i]-minn[i]));
t+=sqr(max(0,maxx[i]-qp[i]));
}
return sqrt(t);
}
}T[N];
void Update(int rt)
{
for(int i=0;i<2;++i)
if(T[rt].ch[i])
for(int j=0;j<kd;++j)
{
T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
}
}
db Dis(int a[],int b[])
{
db t=0;
for(int i=0;i<kd;++i)
t+=sqr(a[i]-b[i]);
return sqrt(t);
}
bool operator < (const Node &a,const Node &b){return a.p[dn]<b.p[dn];}
int Buildtree(int l=1,int r=n,int d=0)
{
dn=d;
int m=(l+r>>1);
nth_element(T+l,T+m,T+r+1);
T[m].Init();
if(l!=m) T[m].ch[0]=Buildtree(l,m-1,(d+1)%kd);
if(m!=r) T[m].ch[1]=Buildtree(m+1,r,(d+1)%kd);
Update(m);
return m;
}
void Query(int rt=root)
{
db t=Dis(T[rt].p,qp);
if(Heap.size()<K)
Heap.push(Ans(T[rt].p,T[rt].id,t));
else if(Heap.top().d-t<-EPS || (fabs(Heap.top().d-t)<EPS && T[rt].id<Heap.top().id))
{
Heap.pop();
Heap.push(Ans(T[rt].p,T[rt].id,t));
}
db dd[2];
for(int i=0;i<2;i++)
if(T[rt].ch[i])
dd[i]=T[T[rt].ch[i]].Dis();
else dd[i]=-INF;
bool f=(dd[0]>=dd[1]);
if((dd[!f]-Heap.top().d>EPS || Heap.size()<K) && T[rt].ch[!f]) Query(T[rt].ch[!f]);
if((dd[f]-Heap.top().d>EPS || Heap.size()<K) && T[rt].ch[f]) Query(T[rt].ch[f]);
}
int q;
int main()
{
// freopen("bzoj2626.in","r",stdin);
// freopen("bzoj3053.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
for(int j=0;j<kd;++j)
scanf("%d",&T[i].p[j]);
T[i].id=i;
}
Buildtree();
root=(1+n>>1);
scanf("%d",&q);
for(;q;--q)
{
while(!Heap.empty())
Heap.pop();
for(int i=0;i<kd;++i)
scanf("%d",&qp[i]);
scanf("%d",&K);
Query();
printf("%d\n",Heap.top().id);
}
return 0;
}

【堆】【kd-tree】bzoj2626 JZPFAR的更多相关文章

  1. [学习笔记]K-D Tree

    以前其实学过的但是不会拍扁重构--所以这几天学了一下 \(K-D\ Tree\) 的正确打开姿势. \(K\) 维 \(K-D\ Tree\) 的单次操作最坏时间复杂度为 \(O(k\times n^ ...

  2. 初涉k-d tree

    听说k-d tree是一个骗分的好东西?(但是复杂度差评??? 还听说绍一的kdt常数特别小? KDT是什么 KDT的全称是k-degree tree,顾名思义,这是一种处理多维空间的数据结构. 例如 ...

  3. k-d tree 学习笔记

    以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...

  4. K-D Tree题目泛做(CXJ第二轮)

    题目1: BZOJ 2716 题目大意:给出N个二维平面上的点,M个操作,分为插入一个新点和询问到一个点最近点的Manhatan距离是多少. 算法讨论: K-D Tree 裸题,有插入操作. #inc ...

  5. BZOJ 4520: [Cqoi2016]K远点对(k-d tree)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1162  Solved: 618[Submit][Status][Discuss] Descripti ...

  6. BZOJ4520:[CQOI2016]K远点对(K-D Tree)

    Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标 ...

  7. AOJ DSL_2_C Range Search (kD Tree)

    Range Search (kD Tree) The range search problem consists of a set of attributed records S to determi ...

  8. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

  9. K-D Tree

    这篇随笔是对Wikipedia上k-d tree词条的摘录, 我认为解释得相当生动详细, 是一篇不可多得的好文. Overview A \(k\)-d tree (short for \(k\)-di ...

  10. k-d Tree in TripAdvisor

    Today, TripAdvisor held a tech talk in Columbia University. The topic is about k-d Tree implemented ...

随机推荐

  1. dataguard 归档丢失(主库中无此丢失归档处理),备库基于SCN恢复

    dataguard 归档丢失(主库中无此丢失归档处理),备库基于SCN恢复 环境: OS: CentOS 6.5 DB: Oracle 10.2.0.5 1.主备库环境 主库: SQL> sel ...

  2. python os.system()返回值判断

    最近遇到os.system()执行系统命令的情况,上网搜集了一下资料,整理如下,以备不时之需,同时也希望能帮到某些人. 一.python中的 os.system(cmd)的返回值与linux命令返回值 ...

  3. AX2012 审批流流转到已停用的域账号导致审批流停止

    AX 2012 中当审批流流转到某个节点时,如果在该节点的审批人的域账号被停用,审批流将会停止,会报如图的错误: 要解决这个问题,得修改标准功能,需要修改SysWorkflow和SysWorkflow ...

  4. MFC使用TRACKMOUSEEVENT触发mouseHover和mouseLeave

    为对话框添加WM_MOUSEHOVER或WM_MOUSELEAVE消息并不会响应.MFC需要特殊处理,其中一法就是使用TRACKMOUSEEVENT void CmfcDlgDlg::OnMouseM ...

  5. Python自动化 【第一篇】:Python简介和入门

    Python简介: 一.什么是python Python是一门动态解释性的强类型定义语言. pythonde 特点:“优雅”.“明确”.“简单”. 二.Python由来 python的创始人为吉多·范 ...

  6. Shell_参数替换(転)

    From: http://www.cnblogs.com/yjf512/archive/2013/06/03/3114803.html Bash中的$符号的作用是参数替换,将参数名替换为参数所代表的值 ...

  7. css3伸缩布局属性总结

    http://www.css88.com/book/css/properties/flex/flex-basis.htm http://c7sky.com/dive-into-flexbox.html ...

  8. javascript 函数执行上下文

    在js里,每个函数都有一个执行的上下文,我们可以通过this来访问. 如: 全局函数 function test(){ var local = this; } 我们发现local等于window(do ...

  9. c++学习笔记——智能指针

    智能指针是为了便于管理动态内存,能够自动管理释放所指向的对象. 智能指针共有三种:1.shared_ptr允许多个指针指向同一个对象:2.unique_ptr独占所指向的对象:3.weak_ptr是一 ...

  10. iOS 拨打电话三种方法

    小弟查了很多地方的关于iOS程序拨打电话,大都不全,今天我总结了三种方法,各有不同,拿来给大家分享,希望给大家有所帮助1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出 ...