zoukankan      html  css  js  c++  java
  • bzoj2648/2716 kdtree

    SJY摆棋子

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

    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可以过

    Source

     
    题解:kdtree的应用,查询最近的距离,就是缩小范围,和最优性剪枝即可过了。
      1 #include<cstring>
      2 #include<cmath>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cstdio>
      6 
      7 #define inf 1000000007
      8 #define N 500007
      9 #define ll long long
     10 using namespace std;
     11 inline int read()
     12 {
     13     int x=0,f=1;char ch=getchar();
     14     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
     15     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 
     19 int n,m,rt,F;
     20 struct Node
     21 {
     22     int d[2],mn[2],mx[2],l,r;
     23     int& operator[](int x)
     24     {
     25         return d[x];
     26     }
     27     Node(int x=0,int y=0)//无代入的话x,y为0,代入即为代入值。 
     28     {
     29         l=0,r=0;
     30         d[0]=x,d[1]=y;
     31     }
     32 }p[N];
     33 bool operator<(Node x,Node y)
     34 {
     35     return x[F]<y[F];
     36 }
     37 inline int dis(Node x,Node y)
     38 {
     39     return abs(x[0]-y[0])+abs(x[1]-y[1]);
     40 }
     41 struct kdtree
     42 {
     43     int ans;
     44     Node tr[N*2],T;
     45     void update(int p)
     46     {
     47         Node l=tr[tr[p].l],r=tr[tr[p].r];
     48         for (int i=0;i<2;i++)
     49         {
     50             if (tr[p].l)tr[p].mn[i]=min(tr[p].mn[i],l.mn[i]),tr[p].mx[i]=max(tr[p].mx[i],l.mx[i]);
     51             if (tr[p].r)tr[p].mn[i]=min(tr[p].mn[i],r.mn[i]),tr[p].mx[i]=max(tr[p].mx[i],r.mx[i]);
     52         }
     53     }
     54     int build(int l,int r,int now)
     55     {
     56         F=now;int mid=(l+r)>>1;
     57         nth_element(p+l,p+mid,p+r+1);
     58         tr[mid]=p[mid];
     59         for (int i=0;i<2;i++)
     60             tr[mid].mn[i]=tr[mid].mx[i]=tr[mid][i];
     61         if (l<mid)tr[mid].l=build(l,mid-1,now^1);
     62         if (r>mid)tr[mid].r=build(mid+1,r,now^1);
     63         update(mid);
     64         return mid;    
     65     }
     66     void ins(int p,int now)
     67     {
     68         if (T[now]>=tr[p][now])
     69         {
     70             if(tr[p].r)ins(tr[p].r,now^1);
     71             else
     72             {
     73                 tr[p].r=++n,tr[n]=T;
     74                 for (int i=0;i<2;i++)
     75                     tr[n].mn[i]=tr[n].mx[i]=tr[n][i];
     76             }
     77         }
     78         else
     79         {
     80             if (tr[p].l)ins(tr[p].l,now^1);
     81             else
     82             {
     83                 tr[p].l=++n,tr[n]=T;
     84                 for (int i=0;i<2;i++)
     85                     tr[n].mn[i]=tr[n].mx[i]=tr[n][i];
     86             }
     87         }
     88         update(p);
     89     }
     90     int get(int k,Node p)
     91     {
     92         int tmp=0;
     93         for (int i=0;i<2;i++)
     94             tmp+=max(0,tr[k].mn[i]-p[i]);
     95         for (int i=0;i<=2;i++)
     96              tmp+=max(0,p[i]-tr[k].mx[i]);
     97         return tmp;     
     98     }
     99     void query(int p,int now)
    100     {
    101         int d,dl=inf,dr=inf;
    102         d=dis(tr[p],T);
    103         ans=min(ans,d);
    104         if (tr[p].l)dl=get(tr[p].l,T);
    105         if (tr[p].r)dr=get(tr[p].r,T);    
    106         if (dl<dr)
    107         {
    108             if (dl<ans)query(tr[p].l,now^1);
    109             if (dr<ans)query(tr[p].r,now^1); 
    110         }
    111         else
    112         {
    113             if (dr<ans)query(tr[p].r,now^1);
    114             if (dl<ans)query(tr[p].l,now^1);
    115         }    
    116     }
    117     int query(Node p)
    118     {
    119         ans=inf,T=p,query(rt,0);
    120         return ans;
    121     }
    122     void ins(Node p)
    123     {
    124         T=p;
    125         ins(rt,0);
    126     }
    127 }kd;
    128 int main()
    129 {
    130     freopen("fzy.in","r",stdin);
    131     freopen("fzy.out","w",stdout);
    132     
    133     n=read(),m=read();
    134     for (int i=1;i<=n;i++)
    135         p[i][0]=read(),p[i][1]=read();
    136     rt=kd.build(1,n,0);//后者0,代表维的循环 
    137     while(m--)
    138     {
    139         int flag=read(),x=read(),y=read();
    140         if (flag==1) kd.ins(Node(x,y));
    141         else printf("%d
    ",kd.query(Node(x,y)));
    142     }
    143 }
  • 相关阅读:
    由PhysicalFileProvider构建的物理文件系统
    Net Core WebApi单元测试
    多个项目使用NET Core
    ReactNative
    定制样式插入到ueditor
    ES6的Class
    Redis存储Session
    二叉 查找树 排序树 搜索树
    SignalR实现实时日志监控
    KNN(k-nearest neighbor的缩写)又叫最近邻算法
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8176561.html
Copyright © 2011-2022 走看看