zoukankan      html  css  js  c++  java
  • 【BZOJ2648】【kd_tree】SJY摆棋子

    Description
     
    这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
     
    Input
     
    第一行两个数 N M
    以后M行,每行3个数 t x y
    如果t=1 那么放下一个黑色棋子
    如果t=2 那么放下一个白色棋子
    Output
     
    对于每个T=2 输出一个最小距离
     
    Sample Input
     
    2 3
     
    1 1
     
    2 3
     
    2 1 2
     
    1 3 3
     
    2 4 2
     
    Sample Output
    1
     
    2
    HINT
     
     
    kdtree可以过
    【分析】
    大家都知道kd_tree是什么吧,恩
    就这样了..好吧,kd_tree一种空间树..看代码就知道了
      1 /*
      2 唐代李白
      3 《江夏别宋之悌》
      4 楚水清若空,遥将碧海通。人分千里外,兴在一杯中。
      5 谷鸟吟晴日,江猿啸晚风。平生不下泪,于此泣无穷.
      6 */
      7 #include <iostream>
      8 #include <cstdio>
      9 #include <algorithm>
     10 #include <cstring>
     11 #include <vector>
     12 #include <utility>
     13 #include <iomanip>
     14 #include <string>
     15 #include <cmath>
     16 #include <queue>
     17 #include <assert.h>
     18 #include <map>
     19 #include <ctime>
     20 #include <cstdlib>
     21 #include <stack>
     22 #include <set> 
     23 #define LOCAL
     24 const int INF = 0x7fffffff;
     25 const int MAXN = 100000  + 10;
     26 const int maxnode = 20000 * 2 + 200000 * 20;
     27 const int MAXM = 50000 + 10;
     28 const int MAX = 100000000;
     29 using namespace std;
     30 struct Node{//kd_tree 
     31    int d[2], l, r;
     32    int Max[2], Min[2];
     33 }t[1000000 + 10],tmp;
     34 
     35 int n,m,root,cmp_d;
     36 int k1, k2, k3, Ans;
     37 
     38 bool cmp(Node a, Node b){return (a.d[cmp_d]<b.d[cmp_d]) || ((a.d[cmp_d] == b.d[cmp_d]) && (a.d[!cmp_d] < b.d[!cmp_d]));}
     39 void update(int p){
     40      if (t[p].l){
     41         //左边最大的横坐标值 
     42         t[p].Max[0] = max(t[p].Max[0], t[t[p].l].Max[0]);
     43         t[p].Min[0] = min(t[p].Min[0], t[t[p].l].Min[0]);
     44         t[p].Max[1] = max(t[p].Max[1], t[t[p].l].Max[1]);
     45         t[p].Min[1] = min(t[p].Min[1], t[t[p].l].Min[1]);
     46      }
     47      if (t[p].r){
     48         t[p].Max[0] = max(t[p].Max[0], t[t[p].r].Max[0]);
     49         t[p].Min[0] = min(t[p].Min[0], t[t[p].r].Min[0]);
     50         t[p].Max[1] = max(t[p].Max[1], t[t[p].r].Max[1]);
     51         t[p].Min[1] = min(t[p].Min[1], t[t[p].r].Min[1]);
     52      }
     53      return;
     54 }
     55 //d是横竖切.. 
     56 int build(int l, int r, int D){
     57     int mid = (l + r) / 2;
     58     cmp_d = D;
     59     //按照cmp的比较顺序在l到r中找到第mid大的元素 
     60     nth_element(t + l + 1, t + mid + 1, t + r + 1, cmp);
     61     t[mid].Max[0] = t[mid].Min[0] = t[mid].d[0];
     62     t[mid].Max[1] = t[mid].Min[1] = t[mid].d[1];
     63     //递归建树 
     64     if (l != mid) t[mid].l = build(l, mid - 1, D ^ 1);
     65     if (r != mid) t[mid].r = build(mid + 1, r, D ^ 1);
     66     update(mid);
     67     return mid;
     68 }
     69 void insert(int now){
     70      int D = 0, p = root;//D还是表示方向
     71      while (1){
     72            //边下传边更新 
     73            t[p].Max[0] = max(t[p].Max[0], t[now].Max[0]);
     74            t[p].Min[0] = min(t[p].Min[0], t[now].Min[0]);
     75            t[p].Max[1] = max(t[p].Max[1], t[now].Max[1]);
     76            t[p].Min[1] = min(t[p].Min[1], t[now].Min[1]);
     77            //有没有点线段树的感觉.. 
     78            if (t[now].d[D] >= t[p].d[D]){
     79               if (t[p].r == 0){
     80                  t[p].r = now;
     81                  return;
     82               }else p = t[p].r;
     83            }else{
     84               if (t[p].l == 0){
     85                  t[p].l = now;
     86                  return;
     87               }else p = t[p].l;
     88            }
     89            D = D ^ 1; 
     90      } 
     91      return;
     92 }
     93 int ABS(int x) {return x < 0? -x : x;}
     94 //dist越小代表越趋近? 
     95 int dist(int p1, int px, int py){
     96     int dist = 0;
     97     if (px < t[p1].Min[0]) dist += t[p1].Min[0] - px;
     98     if (px > t[p1].Max[0]) dist += px - t[p1].Max[0];
     99     if (py < t[p1].Min[1]) dist += t[p1].Min[1] - py;
    100     if (py > t[p1].Max[1]) dist += py - t[p1].Max[1];
    101     return dist; 
    102 }
    103 void ask(int p){
    104    int dl, dr, d0;
    105    //哈密顿距离 
    106    d0=ABS(t[p].d[0] - k2) + ABS(t[p].d[1] - k3);
    107    if(d0 < Ans) Ans = d0;
    108    if(t[p].l) dl = dist(t[p].l, k2, k3); else dl = 0x7f7f7f7f;
    109    if(t[p].r) dr = dist(t[p].r, k2, k3); else dr = 0x7f7f7f7f;
    110    //应该是一个启发式的过程。 
    111    if(dl < dr){
    112        if(dl < Ans) ask(t[p].l);
    113        if(dr < Ans) ask(t[p].r);
    114    }else{
    115        if(dr < Ans) ask(t[p].r);
    116        if(dl < Ans) ask(t[p].l);
    117    }
    118 }
    119 
    120 void init(){
    121      //假设0为横坐标 
    122      scanf("%d%d", &n, &m);
    123      for (int i = 1; i <= n; i++)
    124      scanf("%d%d", &t[i].d[0], &t[i].d[1]);
    125      root = build(1, n, 0);
    126 }
    127 void work(){
    128      for (int i = 1; i <= m ;i++){
    129          scanf("%d%d%d", &k1, &k2, &k3);
    130          if (k1 == 1){//黑棋 
    131             ++n;
    132             t[n].Max[0] = t[n].Min[0] = t[n].d[0] = k2;
    133             t[n].Max[1] = t[n].Min[1] = t[n].d[1] = k3;
    134             insert(n);
    135          }else{
    136             Ans = 0x7f7f7f7f;
    137             ask(root);
    138             printf("%d
    ", Ans);
    139          }
    140      }
    141 }
    142 
    143 int main(){
    144    
    145    init(); 
    146    work();
    147    return 0; 
    148 }
    View Code
     
  • 相关阅读:
    ASP.NET的最新安全漏洞Important: ASP.NET Security Vulnerability
    Sql常用日期格式
    倒计时 服务器时间 .NET js javascript
    “备份集中的数据库备份与现有的数据库不同”解决方法
    2010年最佳jQuery插件
    jQuery1.4与json格式兼容问题
    .NET结束外部进程 C#结束外部进程
    十步优化SQL Server中的数据访问
    SQL游标的使用与语法
    SQL2005、SQL2008如何压缩日志文件(log) 如何清除日志
  • 原文地址:https://www.cnblogs.com/hoskey/p/4346269.html
Copyright © 2011-2022 走看看