• Hdu-5992 2016ACM/ICPC亚洲区青岛站 K.Finding Hotels KDtree


    题面

    题意:二维平面上有很多点,每个点有个权值,现在给你一个点(很多组),权值v,让你找到权值小于等于v的点中离这个点最近的,相同的输出id小的

    题解:很裸的KDtree,但是查询的时候有2个小限制,

            1个是要小于等于v,1个是输出最小id

             第一个,对每个点判断dis的时候 如果价钱高于v 距离就变为INF 低于v就没有影响

             第二个,如果disl或者disr 和当前最近的dis 相等 就继续询问以得到更小的id 

     1 #include<bits/stdc++.h>
     2 typedef long long ll;
     3 using namespace std;
     4 const int N=2e5+5;
     5 const ll INF=1e18;
     6 int T,n,m;
     7 struct point 
     8 {
     9     ll x[2];
    10     int c,id;
    11 }p[N],d;
    12 ll idd,ansid,ans;
    13 ll sqr(ll x) {return x*x;}
    14 int cur;
    15 bool cmp(point a,point b) 
    16 {
    17     return a.x[cur]<b.x[cur];
    18 }
    19 void build(int l,int r,int dep)
    20 {
    21     if(l>=r) return;
    22     int mid=(l+r)>>1;
    23     cur=dep%2;
    24     nth_element(p+l,p+mid,p+r+1,cmp);
    25     build(l,mid-1,dep+1);
    26     build(mid+1,r,dep+1);
    27 }
    28 ll dis(point a,point b) 
    29 {
    30     ll ans=0;
    31     for(int i=0;i<2;++i) ans+=sqr(a.x[i]-b.x[i]);
    32     return ans;
    33 }
    34 ll ff(point x,int l,int r,int dep) 
    35 {
    36     int cur=dep%2;
    37     if(l>=r) {
    38         if(l==r&&x.c>=p[l].c) {
    39             ll cnt=dis(x,p[l]);
    40             if(p[l].c<=x.c&&(cnt<ans||(cnt==ans&&p[l].id<ansid))) 
    41             {
    42                 ansid=p[l].id;
    43                 ans=cnt;
    44                 idd=l;
    45             }
    46         }
    47         return INF;
    48     }
    49     int mid=(l+r)>>1;
    50     ll res=dis(x,p[mid]);
    51     if(p[mid].c<=x.c&&(res<ans||(res==ans&&p[mid].id<ansid))) 
    52     {
    53         ans=res;ansid=p[mid].id;
    54         idd=mid;
    55     }
    56     ll tmp;
    57     if(x.x[cur]<p[mid].x[cur]) 
    58     {
    59         tmp=ff(x,l,mid-1,dep+1);
    60         if(ans>sqr(x.x[cur]-p[mid].x[cur])) ff(x,mid+1,r,dep+1);
    61     }
    62     else 
    63     {
    64         tmp=ff(x,mid+1,r,dep+1);
    65         if(ans>sqr(x.x[cur]-p[mid].x[cur])) ff(x,l,mid-1,dep+1);
    66     }
    67 }
    68 int main() 
    69 {
    70     scanf("%d",&T);
    71     while(T--) 
    72     {
    73         scanf("%d%d",&n,&m);
    74         for(int i=0;i<n;++i) 
    75         {
    76             scanf("%d%d%d",&p[i].x[0],&p[i].x[1],&p[i].c);
    77             p[i].id=i;
    78         }
    79         build(0,n-1,0);
    80         while(m--) 
    81         {
    82             scanf("%d%d%d",&d.x[0],&d.x[1],&d.c);
    83             ans=INF;
    84             ff(d,0,n-1,0);
    85             printf("%lld %lld %lld
    ",p[idd].x[0],p[idd].x[1],p[idd].c);
    86         }
    87     }
    88 }
  • 相关阅读:
    动词的形态及变化(转)
    数论基础
    P1505 [国家集训队]旅游
    贪心常见题
    主席树
    卡常火车头
    AC自动机
    左偏树
    位运算
    Linux下Vim常用操作
  • 原文地址:https://www.cnblogs.com/qywhy/p/9741133.html
Copyright © 2020-2023  润新知