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

#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 学习笔记

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

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

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

  3. 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 ...

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

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

  5. K-D Tree

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

  6. k-d Tree in TripAdvisor

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

  7. k-d tree算法

    k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...

  8. kd tree学习笔记 (最近邻域查询)

    https://zhuanlan.zhihu.com/p/22557068 http://blog.csdn.net/zhjchengfeng5/article/details/7855241 KD树 ...

  9. KD Tree算法

    参考:http://blog.csdn.net/v_july_v/article/details/8203674 #!/user/bin/env python # -*- coding:utf8 -* ...

随机推荐

  1. 玩转Windows服务系列——使用Boost.Application快速构建Windows服务

    玩转Windows服务系列——创建Windows服务一文中,介绍了如何快速使用VS构建一个Windows服务.Debug.Release版本的注册和卸载,及其原理和服务运行.停止流程浅析分别介绍了Wi ...

  2. java发送http的get、post请求

    转载博客:http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html Http请求类 package wzh.Http; impor ...

  3. CAS实现SSO单点登录原理

    1.      CAS 简介 1.1.  What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...

  4. crm 2013邮箱设置 “允许使用凭据进行电子邮件处理” 被禁用的解决

    记录一下: 在CRM 2013/2015的邮箱设置时发现“允许使用凭据进行电子邮件处理” 选项被禁用而且无法输入凭证(如下图): 查阅官方说明得知考虑邮件安全性只能在IFD部署或https访问模式下才 ...

  5. 完美演绎DevExpress XtraPrinting Library 的打印功能

    完美演绎DevExpress XtraPrinting Library 的打印功能 2010-05-14 17:40:49|  分类: 默认分类|字号 订阅     设计报告不仅费时间,而且还乏味!但 ...

  6. CocoaPods安装与使用

    CocoaPods简介: CocoaPods 是什么? CocoaPods 是开发 OS X 和 iOS 应用程序的一个第三方库的依赖管理工具.利用 CocoaPods,可以定义自己的依赖关系 (称作 ...

  7. ajax实现文件上传

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  8. 关于Task类

    private static void tt2() { Task task = null; ; i < ; i++) { task = Task.Factory.StartNew(callbac ...

  9. emulator: ERROR: x86 emulation currently requires hardware acceleration!

    emulator: ERROR: x86 emulation currently requires hardware acceleration!Please ensure Intel  is prop ...

  10. [编解码] 关于base64编码的原理及实现

    转载自: http://www.cnblogs.com/hongru/archive/2012/01/14/2321397.html [Base64]-base64的编码都是按字符串长度,以每3个8b ...