• 【堆】【kd-tree】bzoj2626 JZPFAR


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

    #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
    ",Heap.top().id);
          }
        return 0;
    }
  • 相关阅读:
    leetcode 3sum
    leetcode majority elements
    php调取linux的压缩命令进行压缩
    mysql 分区、分表、分库分表。
    如何在数据库中使用索引
    PDO 的基本操作
    JavaScript中常见的字符串操作函数及用法汇总
    php-fpm
    phpmyadmin导入导出数据库文件最大限制的解决方法
    php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳。
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587126.html
Copyright © 2020-2023  润新知