zoukankan      html  css  js  c++  java
  • 模板—K-D-tree(P2479 [SDOI2010]捉迷藏)

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #define LL long long
      6 #define MAXN 1000100
      7 using namespace std;
      8 inline LL min(LL a,LL b){return a<b?a:b;}
      9 int n,cmpid;
     10 struct point
     11 {   
     12     int x[2];
     13     friend bool operator < (point a,point b)
     14     {return a.x[cmpid]<b.x[cmpid];}
     15 }p[MAXN];
     16 struct tree
     17 {
     18     point p;
     19     int mn[2],mx[2],l,r;
     20     #define l(x) tr[x].l
     21     #define r(x) tr[x].r
     22     #define p(x) tr[x].p
     23 }tr[MAXN];
     24 int Dis(point a,point b)
     25 {
     26     return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);
     27 }
     28 int min_dis(tree a,point b)
     29 {
     30     int x=max(a.mn[0]-b.x[0],0)+max(b.x[0]-a.mx[0],0);
     31     int y=max(a.mn[1]-b.x[1],0)+max(b.x[1]-a.mx[1],0);    
     32     return x+y;
     33 }
     34 int max_dis(tree a,point b)
     35 {
     36     int x=max(abs(a.mx[0]-b.x[0]),abs(b.x[0]-a.mn[0]));
     37     int y=max(abs(a.mx[1]-b.x[1]),abs(b.x[1]-a.mn[1]));
     38     return x+y;
     39 }
     40 struct KDtree
     41 {
     42     int root,tot,ans;
     43     #define INF 0x7fffffff
     44     void ask_max(point a,int x,int k)
     45     {
     46         if(!x)return;int tem;
     47         if((tem=Dis(p(x),a))>ans)ans=tem;
     48         int l=l(x),r=r(x);
     49         if(a.x[k]<p(x).x[k])swap(l,r);
     50         if(max_dis(tr[l],a)>ans)ask_max(a,l,k^1);
     51         if(max_dis(tr[r],a)>ans)ask_max(a,r,k^1);
     52     }
     53     int ask_max(point a)
     54     {
     55         ans=-INF;
     56         ask_max(a,root,0);
     57         return ans;
     58     }
     59     void ask_min(point a,int x,int k)
     60     {    
     61         if(!x)return;int tem;
     62         if((tem=Dis(p(x),a))<ans&&tem!=0)ans=tem;
     63         int l=l(x),r=r(x);
     64         if(a.x[k]>p(x).x[k])swap(l,r);//如果a在x有右半区间,先向右搜索。
     65         if(min_dis(tr[l],a)<ans)ask_min(a,l,k^1);
     66         if(min_dis(tr[r],a)<ans)ask_min(a,r,k^1);
     67     }
     68     int ask_min(point a)
     69     {
     70         ans=INF;
     71         ask_min(a,root,0);
     72         return ans;
     73     }
     74     void updata(int x)
     75     {
     76         if(!x)return;
     77         if(l(x))
     78             tr[x].mn[0]=min(tr[x].mn[0],tr[l(x)].mn[0]),
     79             tr[x].mn[1]=min(tr[x].mn[1],tr[l(x)].mn[1]),
     80             tr[x].mx[0]=max(tr[x].mx[0],tr[l(x)].mx[0]),
     81             tr[x].mx[1]=max(tr[x].mx[1],tr[l(x)].mx[1]);
     82         if(r(x))
     83             tr[x].mn[0]=min(tr[x].mn[0],tr[r(x)].mn[0]),    
     84             tr[x].mn[1]=min(tr[x].mn[1],tr[r(x)].mn[1]),
     85             tr[x].mx[0]=max(tr[x].mx[0],tr[r(x)].mx[0]),
     86             tr[x].mx[1]=max(tr[x].mx[1],tr[r(x)].mx[1]);
     87     }
     88     void build(int &x,int l,int r,int k)
     89     {
     90         if(l>r)return;
     91         x=++tot;int mid=(l+r)>>1;
     92         cmpid=k;
     93         nth_element(p+l,p+mid,p+r+1);
     94         p(x)=p[mid];
     95         tr[x].mn[0]=tr[x].mx[0]=p(x).x[0];
     96         tr[x].mn[1]=tr[x].mx[1]=p(x).x[1];
     97         build(l(x),l,mid-1,k^1);
     98         build(r(x),mid+1,r,k^1);
     99         updata(x);
    100     }
    101     void build()
    102     {
    103         tot=0;
    104         build(root,1,n,0);
    105     }
    106 }T;
    107 signed main()
    108 {    
    109     cin>>n;
    110     for(int i=1;i<=n;i++)    
    111         cin>>p[i].x[0]>>p[i].x[1];
    112     T.build();    
    113     LL ans=INF;
    114     for(int i=1;i<=n;i++)
    115     {
    116         ans=min(ans,T.ask_max(p[i])-T.ask_min(p[i]));
    117     }
    118     cout<<ans<<endl;
    119 }
    120     
    View Code

     放一下‘天使玩偶’的标程:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    using namespace std;
    int n,m,cmpid;
    struct point
    {
        int x[2];
        friend bool operator < (point a,point b)
        {return a.x[cmpid]<b.x[cmpid];}
    }p[510000];
    struct tree
    {
        point p;
        int mx[2],mn[2],l,r;
        #define l(x) tr[x].l
        #define r(x) tr[x].r
        #define p(x) tr[x].p
    }tr[10000000];
    int dis(point a,point b){return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);}
    int min_dis(tree a,point b)
    {
        int x=max(a.mn[0]-b.x[0],0)+max(b.x[0]-a.mx[0],0);
        int y=max(a.mn[1]-b.x[1],0)+max(b.x[1]-a.mx[1],0);
        return x+y;
    }
    struct KD_tree
    {
        int root,tot,ans;
        #define INF 0x7fffffff
        void ask_min(point a,int x,int k)
        {
            if(!x)return;int tem;
            if((tem=dis(p(x),a))<ans)ans=tem;
            int l=l(x),r=r(x);
            if(a.x[k]>p(x).x[k])swap(l,r);
            if(min_dis(tr[l],a)<ans)ask_min(a,l,k^1);
            if(min_dis(tr[r],a)<ans)ask_min(a,r,k^1);
        }
        int ask_min(point a)
        {
            ans=INF;ask_min(a,root,0);
            return ans;
        }
        void updata(int x)
        {
            if(!x)return;
            if(l(x))
                tr[x].mn[0]=min(tr[x].mn[0],tr[l(x)].mn[0]),
                tr[x].mn[1]=min(tr[x].mn[1],tr[l(x)].mn[1]),
                tr[x].mx[0]=max(tr[x].mx[0],tr[l(x)].mx[0]),
                tr[x].mx[1]=max(tr[x].mx[1],tr[l(x)].mx[1]);
            if(r(x))
                tr[x].mn[0]=min(tr[x].mn[0],tr[r(x)].mn[0]),
                tr[x].mn[1]=min(tr[x].mn[1],tr[r(x)].mn[1]),
                tr[x].mx[0]=max(tr[x].mx[0],tr[r(x)].mx[0]),
                tr[x].mx[1]=max(tr[x].mx[1],tr[r(x)].mx[1]);
        }
        void build(int &x,int l,int r,int k)
        {
            if(l>r)return;
            x=++tot;int mid=(l+r)>>1;
            cmpid=k;
            nth_element(p+l,p+mid,p+r+1);
            p(x)=p[mid];
            tr[x].mn[0]=tr[x].mx[0]=p(x).x[0];
            tr[x].mn[1]=tr[x].mx[1]=p(x).x[1];
            build(l(x),l,mid-1,k^1);
            build(r(x),mid+1,r,k^1);
            updata(x);
        }
        void build(){tot=0;build(root,1,n,0);}
        void insert(point a,int &x,int k)
        {
            if(!x)
            {
                x=++tot;p(x)=a;
                tr[x].mn[0]=tr[x].mx[0]=p(x).x[0];
                tr[x].mn[1]=tr[x].mx[1]=p(x).x[1];
                return;
            }
            if(a.x[k]<p(x).x[k])insert(a,l(x),k^1);
            else insert(a,r(x),k^1);
            updata(x);
        }
        void insert(point a){insert(a,root,0);}
    }T;
    signed main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>p[i].x[0]>>p[i].x[1];
        T.build();int t,x,y;
        for(int i=1;i<=m;i++)
        {    
            cin>>t>>x>>y;
            if(t==1)T.insert((point){x,y});
            else cout<<T.ask_min((point){x,y})<<endl;;
        }
    }
  • 相关阅读:
    思考-少写代码
    app上传 那些事儿!
    vs2010 找不到本地服务器
    如何成为一名优秀得程序员
    python成功之路,Day2-判断和循环语句
    python成功之路,Day1-发展历史
    ES6学习笔记2-字符串扩展
    ES6学习笔记1-解构赋值
    数组的方法
    ES6
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11297379.html
Copyright © 2011-2022 走看看