zoukankan      html  css  js  c++  java
  • BZOJ4520:[CQOI2016]K远点对(K-D Tree)

    Description

    已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。

    Input

    输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点
    的坐标。1 < =  N < =  100000, 1 < =  K < =  100, K < =  N*(N−1)/2 , 0 < =  X, Y < 2^31。

    Output

    输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。

    Sample Input

    10 5
    0 0
    0 1
    1 0
    1 1
    2 0
    2 1
    1 2
    0 2
    3 0
    3 1

    Sample Output

    9

    Solution

    到现在为止只会写K-D Tree的板子题……
    这次画了个图又理解了一下估价函数,感觉挺不错的
    按照套路维护k远开个堆就好了,只不过由于这个题(x,y)和(y,x)算一对
    需要开2*k的堆最后输出堆顶

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<queue>
      7 #include<algorithm>
      8 #define N (100000+1000)
      9 #define INF 1e17
     10 using namespace std;
     11 
     12 struct P
     13 {
     14     long long dis,num;
     15     bool operator < (const P &a) const{return dis>a.dis;}
     16 }po;
     17 long long n,k,D,Root;
     18 priority_queue<P>q;
     19 
     20 struct Node
     21 {
     22     long long d[2],Max[2],Min[2],lson,rson;
     23     bool operator < (const Node &a) const {return d[D]<a.d[D];}
     24 }p[N],T;
     25 
     26 struct KDT
     27 {
     28     Node Tree[N];
     29     long long sqr(long long x){return x*x;}
     30     
     31     void Update(long long now)
     32     {
     33         for (int i=0; i<=1; ++i)
     34         {
     35             long long ls=Tree[now].lson, rs=Tree[now].rson;
     36             Tree[now].Max[i]=Tree[now].Min[i]=Tree[now].d[i];
     37             if (ls)
     38             {
     39                 Tree[now].Max[i]=max(Tree[now].Max[i],Tree[ls].Max[i]);
     40                 Tree[now].Min[i]=min(Tree[now].Min[i],Tree[ls].Min[i]);
     41             }
     42             if (rs)
     43             {
     44                 Tree[now].Max[i]=max(Tree[now].Max[i],Tree[rs].Max[i]);
     45                 Tree[now].Min[i]=min(Tree[now].Min[i],Tree[rs].Min[i]);
     46             }
     47         }
     48     }
     49     long long Build(long long opt,long long l,long long r)
     50     {
     51         if (l>r) return 0;
     52         long long mid=(l+r)>>1;
     53         D=opt; nth_element(p+l,p+mid,p+r+1);
     54         Tree[mid]=p[mid];
     55         Tree[mid].lson=Build(opt^1,l,mid-1);
     56         Tree[mid].rson=Build(opt^1,mid+1,r);
     57         Update(mid); return mid;
     58     }
     59     long long Get_max(long long now)
     60     {
     61         long long ans=0;
     62         for (int i=0; i<=1; ++i)
     63             ans+=max(sqr(T.d[i]-Tree[now].Min[i]),sqr(T.d[i]-Tree[now].Max[i]));
     64         return ans;
     65     }
     66     void Query(long long now)
     67     {
     68         long long ls=Tree[now].lson, rs=Tree[now].rson, lans=-INF, rans=-INF;
     69         if (ls) lans=Get_max(ls);
     70         if (rs) rans=Get_max(rs);
     71         
     72         po.dis=sqr(T.d[0]-Tree[now].d[0])+sqr(T.d[1]-Tree[now].d[1]); po.num=now;
     73         if (po.dis>q.top().dis)
     74             q.pop(),q.push(po);
     75         
     76         if (lans>rans)
     77         {
     78             if (lans>q.top().dis) Query(ls);
     79             if (rans>q.top().dis) Query(rs);
     80         }
     81         else
     82         {
     83             if (rans>q.top().dis) Query(rs);
     84             if (lans>q.top().dis) Query(ls);
     85         }
     86     }
     87 }KDT;
     88 
     89 int main()
     90 {
     91     scanf("%lld%lld",&n,&k);
     92     for (int i=1; i<=n; ++i)
     93         scanf("%lld%lld",&p[i].d[0],&p[i].d[1]);
     94     Root=KDT.Build(0,1,n);
     95     
     96     po.dis=-INF,po.num=0;
     97     for (int i=1;  i<=2*k; ++i)
     98         q.push(po);
     99     
    100     for (int i=1; i<=n; ++i)
    101     {
    102         T=KDT.Tree[i];
    103         KDT.Query(Root);
    104     }
    105     printf("%lld",q.top().dis);
    106 }
  • 相关阅读:
    python-configparser模块,xml.etree模块
    Ubuntu16.04环境下Vim 配置 for HTML,CSS,JAVASCRIPT(1)
    Windows 命令行及Git操作
    Ubuntu16.04 无任务栏问题
    ubuntu16.04安装中文输入法
    本地Web服务器搭建
    爬虫(1)
    Python(四):数字连珠2
    python学习(四)五数连珠
    Openjudge 百练第4109题
  • 原文地址:https://www.cnblogs.com/refun/p/9304678.html
Copyright © 2011-2022 走看看