zoukankan      html  css  js  c++  java
  • 【BZOJ2648】SJY摆棋子 [KD-tree]

    SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB
    [Submit][Status][Discuss]

    Description

      这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N个初始棋子,和M个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

    Input

      第一行两个数 N M
      然后N行,每行2个数 x y,表示初始棋子
      以后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

      N<=500000 , M<=500000

    Main idea

      在平面上加入黑点,对于询问一个坐标到其它点的曼哈顿距离中最小的一个。

    Solution

      这题显然是一道KD-tree的模板题。

      我们来考虑如何估价,由于求的是最小的曼哈顿距离,我们可以这样估价:

      

      (其实我也并不懂为什么可以这样估,详情可以查询“n+e KDtree在信息学奥赛中的应用”

    Code

      1 #include<iostream>    
      2 #include<string>    
      3 #include<algorithm>    
      4 #include<cstdio>    
      5 #include<cstring>    
      6 #include<cstdlib>    
      7 #include<cmath>    
      8 #include<map>  
      9 using namespace std;  
     10   
     11 const int ONE=1000005;
     12 const int INF=2147483640;
     13 
     14 int n,m;
     15 int t,x,y;
     16 int cnt,Ans;
     17 int root;
     18 int Ran;
     19 
     20 struct power
     21 {    
     22         int l,r;
     23         int x,y;
     24         int minx,miny;
     25         int maxx,maxy;
     26 }a[ONE];
     27 
     28 int get()
     29 {    
     30         int res=1,Q=1;char c;    
     31         while( (c=getchar())<48 || c>57 ) 
     32         if(c=='-')Q=-1; 
     33         res=c-48;     
     34         while( (c=getchar())>=48 && c<=57 )    
     35         res=res*10+c-48;    
     36         return res*Q;    
     37 }
     38 
     39 namespace KD
     40 {
     41         void Update(int i)
     42         {
     43             if(a[i].l)
     44             {
     45                 a[i].minx=min(a[i].minx,a[a[i].l].minx);    a[i].miny=min(a[i].miny,a[a[i].l].miny);
     46                 a[i].maxx=max(a[i].maxx,a[a[i].l].maxx);    a[i].maxy=max(a[i].maxy,a[a[i].l].maxy); 
     47             }
     48             if(a[i].r)
     49             {
     50                 a[i].minx=min(a[i].minx,a[a[i].r].minx);    a[i].miny=min(a[i].miny,a[a[i].r].miny);
     51                 a[i].maxx=max(a[i].maxx,a[a[i].r].maxx);    a[i].maxy=max(a[i].maxy,a[a[i].r].maxy);
     52             }
     53         }
     54         
     55         int cmp(const power &a,const power &b)
     56         {
     57             if(Ran) return a.x<b.x;
     58             return a.y<b.y;
     59         }
     60         
     61         int Build(int l,int r,int T)
     62         {
     63             int mid=(l+r)/2;
     64             Ran=T;
     65             nth_element(a+l, a+mid+1, a+r+1, cmp);
     66             if(l<mid) a[mid].l = Build(l,mid-1,T^1);
     67             if(mid<r) a[mid].r = Build(mid+1,r,T^1);
     68             Update(mid);
     69             return mid;
     70         }
     71 }
     72 
     73 void Update(int &i,int x,int y,int T)
     74 {
     75         if(!i)
     76         {
     77             i=++cnt;
     78             a[i].x=a[i].minx=a[i].maxx=x;
     79             a[i].y=a[i].miny=a[i].maxy=y;
     80             return;
     81         }
     82         
     83         if(T)
     84         {
     85             if(x < a[i].x) Update(a[i].l,x,y,T^1);
     86             else Update(a[i].r,x,y,T^1);
     87             KD::Update(i);
     88         }
     89         else
     90         {
     91             if(y < a[i].y) Update(a[i].l,x,y,T^1);
     92             else Update(a[i].r,x,y,T^1);
     93             KD::Update(i);
     94         }
     95 }
     96 
     97 int dist(int x1,int y1,int x2,int y2)
     98 {
     99         return abs(x1-x2)+abs(y1-y2);
    100 }
    101 
    102 int dist(int i,int x,int y)
    103 {
    104         return max(a[i].minx-x,0)+max(x-a[i].maxx,0) + max(a[i].miny-y,0)+max(y-a[i].maxy,0);
    105 }
    106 
    107 void Query(int i,int x,int y)
    108 {
    109         if(!i) return;
    110         Ans=min(Ans,dist(x,y , a[i].x,a[i].y));
    111         int l=dist(a[i].l,x,y);
    112         int r=dist(a[i].r,x,y);
    113         if(l<r)
    114         {
    115             if(l<=Ans) Query(a[i].l,x,y);
    116             if(r<=Ans) Query(a[i].r,x,y);
    117         }
    118         else
    119         {
    120             if(r<=Ans) Query(a[i].r,x,y);
    121             if(l<=Ans) Query(a[i].l,x,y);
    122         }
    123 }
    124 
    125 int main()
    126 {
    127         n=get();    m=get();
    128         for(int i=1;i<=n;i++)
    129         {
    130             x=get();    y=get();
    131             a[i].x=a[i].minx=a[i].maxx=x;
    132             a[i].y=a[i].miny=a[i].maxy=y;
    133         }
    134         
    135         cnt=n;
    136         root=KD::Build(1,n,1);
    137         
    138         for(int i=1;i<=m;i++)
    139         {
    140             t=get();    x=get();    y=get();
    141             if(t==1)
    142             {
    143                 n++;
    144                 a[n].x=a[n].minx=a[n].maxx=x;
    145                 a[n].y=a[n].miny=a[n].maxy=y;
    146                 Update(root,x,y,1);
    147             }
    148             else
    149             {
    150                 Ans=INF;
    151                 Query(root,x,y);
    152                 printf("%d
    ",Ans);
    153             }
    154         }
    155 }
    View Code
  • 相关阅读:
    显示器的分类和主要性能指标
    关闭Win 10 自动更新功能
    MySQL下载安装教程
    经济学十大原理
    西方经济学概述(经济学原理 1 )
    工作表基本操作
    输入和编辑工作表
    因特网概述
    摩尔定律(Moore's Law)
    C 语言编程机制
  • 原文地址:https://www.cnblogs.com/BearChild/p/6438826.html
Copyright © 2011-2022 走看看