zoukankan      html  css  js  c++  java
  • BZOJ 4520: [Cqoi2016]K远点对

    4520: [Cqoi2016]K远点对

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 638  Solved: 340
    [Submit][Status][Discuss]

    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

    HINT

     

    Source

     
    [Submit][Status][Discuss]

    建立KD-Tree,用堆维护当前找到的前K远点对。

    枚举一个点,在树中遍历,尝试更新堆顶(较近的点对)。

    注意用KD-Tree“估价函数”来剪枝,还有因为点对有重复,所以应当取出第2K远的点对。

      1 #include <bits/stdc++.h>
      2 
      3 const int siz = 100005;
      4 
      5 int n, m;
      6 
      7 struct node
      8 {
      9     int son[2];
     10     int pos[2];
     11     int maxi[2];
     12     int mini[2];
     13 }tr[siz];
     14 
     15 int cmpk;
     16 
     17 inline bool cmp(const node &a, const node &b)
     18 {
     19     if (a.pos[cmpk] != b.pos[cmpk])
     20         return a.pos[cmpk] < b.pos[cmpk];
     21     else
     22         return a.pos[cmpk^1] < b.pos[cmpk^1];
     23 }
     24 
     25 int build(int l, int r, int k)
     26 {
     27     int mid = (l + r) >> 1; cmpk = k;
     28 
     29     std::nth_element(tr + l, tr + mid, tr + r + 1, cmp);
     30 
     31     if (l < mid)tr[mid].son[0] = build(l, mid - 1, k ^ 1);
     32     if (r > mid)tr[mid].son[1] = build(mid + 1, r, k ^ 1);
     33 
     34     tr[mid].maxi[0] = tr[mid].mini[0] = tr[mid].pos[0];
     35     tr[mid].maxi[1] = tr[mid].mini[1] = tr[mid].pos[1];
     36 
     37     for (int i = 0; i < 2; ++i)if (tr[mid].son[i])
     38         for (int j = 0; j < 2; ++j)
     39         {
     40             if (tr[mid].maxi[j] < tr[tr[mid].son[i]].maxi[j])
     41                 tr[mid].maxi[j] = tr[tr[mid].son[i]].maxi[j];
     42             if (tr[mid].mini[j] > tr[tr[mid].son[i]].mini[j])
     43                 tr[mid].mini[j] = tr[tr[mid].son[i]].mini[j];
     44         }
     45     
     46     return mid;
     47 }
     48 
     49 typedef long long lnt;
     50 
     51 const lnt inf = 2e18;
     52 
     53 std::priority_queue<
     54     lnt, std::vector<lnt>, std::greater<lnt>
     55 > heap;
     56 
     57 int qx, qy;
     58 
     59 inline lnt sqr(lnt x)
     60 {
     61     return x * x;
     62 }
     63 
     64 inline lnt calc(int t)
     65 {
     66     lnt dx = std::max(sqr(tr[t].mini[0] - qx), sqr(tr[t].maxi[0] - qx));
     67     lnt dy = std::max(sqr(tr[t].mini[1] - qy), sqr(tr[t].maxi[1] - qy));
     68 
     69     return dx + dy;
     70 }
     71 
     72 void query(int t)
     73 {
     74     lnt dis = sqr(tr[t].pos[0] - qx) + sqr(tr[t].pos[1] - qy);
     75 
     76     if (dis > heap.top())
     77     {
     78         heap.pop();
     79         heap.push(dis);
     80     }
     81 
     82     lnt dl = tr[t].son[0] ? calc(tr[t].son[0]) : -inf;
     83     lnt dr = tr[t].son[1] ? calc(tr[t].son[1]) : -inf;
     84 
     85     if (dl > dr)
     86     {
     87         if (dl > heap.top())query(tr[t].son[0]);
     88         if (dr > heap.top())query(tr[t].son[1]);
     89     }
     90     else
     91     {
     92         if (dr > heap.top())query(tr[t].son[1]);
     93         if (dl > heap.top())query(tr[t].son[0]);
     94     }
     95 }
     96 
     97 signed main(void)
     98 {
     99     scanf("%d%d", &n, &m);
    100 
    101     for (int i = 1; i <= n; ++i)
    102         scanf("%d%d", &tr[i].pos[0], &tr[i].pos[1]);
    103     
    104     int root = build(1, n, 0);
    105 
    106     for (int i = 1; i <= 2*m; ++i)
    107         heap.push(0LL);
    108     
    109     for (int i = 1; i <= n; ++i)
    110     {
    111         qx = tr[i].pos[0];
    112         qy = tr[i].pos[1];
    113         query(root);
    114     }
    115 
    116     printf("%lld
    ", heap.top());
    117 }

    @Author: YouSiki

  • 相关阅读:
    SpringBoot整合dubbo2.7.12
    linux安装zookeeper
    javaassist创建对象
    jmeter websocket
    jmeter使用
    jmeter返回值乱码
    HTTP 头 Connection:close 作用 和 解决服务器产生大量close_wait问题
    服务器TCP连接中 TIME_WAIT 状态过多
    Chrome 浏览器远程调试 【转】
    拼多多聊天记录监控、拼多多客服机器人代码、拼多多智能机器人代码、拼多多自动发货、拼多多虚拟卡号自动发货
  • 原文地址:https://www.cnblogs.com/yousiki/p/6284724.html
Copyright © 2011-2022 走看看