zoukankan      html  css  js  c++  java
  • [模板]kd-tree

    //It is made by jump~
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #ifdef WIN32
    #define OT "%I64d"
    #else
    #define OT "%lld"
    #endif
    using namespace std;
    typedef long long LL;
    const int MAXN = 1000011;
    const int inf = (1<<30);
    int n,m;
    int nowD;
    int root;
    int ans;
    int ql,qr;
    
    struct node{
        int Min[2],Max[2];
        int d[2];
        int l,r;
    }t[MAXN*2];
    
    inline int getint()
    {
           int w=0,q=0;
           char c=getchar();
           while((c<'0' || c>'9') && c!='-') c=getchar();
           if (c=='-')  q=1, c=getchar();
           while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
           return q ? -w : w;
    }
    
    inline bool cmp(node q,node qq){
        if(q.d[nowD]==qq.d[nowD]) return q.d[!nowD]<qq.d[!nowD];
        return q.d[nowD]<qq.d[nowD];
    }
    
    inline void kd_updata(int now){
        if(t[now].l) {
        if(t[t[now].l].Max[0]>t[now].Max[0]) t[now].Max[0]=t[t[now].l].Max[0];
        if(t[t[now].l].Max[1]>t[now].Max[1]) t[now].Max[1]=t[t[now].l].Max[1];
        if(t[t[now].l].Min[0]<t[now].Min[0]) t[now].Min[0]=t[t[now].l].Min[0];
        if(t[t[now].l].Min[1]<t[now].Min[1]) t[now].Min[1]=t[t[now].l].Min[1];
        }
        if(t[now].r) {
        if(t[t[now].r].Max[0]>t[now].Max[0]) t[now].Max[0]=t[t[now].r].Max[0];
        if(t[t[now].r].Max[1]>t[now].Max[1]) t[now].Max[1]=t[t[now].r].Max[1];
        if(t[t[now].r].Min[0]<t[now].Min[0]) t[now].Min[0]=t[t[now].r].Min[0];
        if(t[t[now].r].Min[1]<t[now].Min[1]) t[now].Min[1]=t[t[now].r].Min[1];
        }
    }
    
    inline int kd_build(int l,int r,int D){
        int mid=(l+r)/2;
        nowD=D;
        nth_element(t+l+1,t+mid+1,t+r+1,cmp);
    
        if(l!=mid) t[mid].l=kd_build(l,mid-1,!D);
        if(r!=mid) t[mid].r=kd_build(mid+1,r,!D);
        t[mid].Max[0]=t[mid].Min[0]=t[mid].d[0];
        t[mid].Max[1]=t[mid].Min[1]=t[mid].d[1];
        kd_updata(mid);
        return mid;
    }
    
    inline int dist(int p){
        int dis=0;
        if(ql<t[p].Min[0]) dis+=t[p].Min[0]-ql;
        if(ql>t[p].Max[0]) dis+=ql-t[p].Max[0];
        if(qr<t[p].Min[1]) dis+=t[p].Min[1]-qr;
        if(qr>t[p].Max[1]) dis+=qr-t[p].Max[1];
        return dis;
    }
    
    inline void kd_query(int p){
        int dl,dr,d0;
        d0=abs(t[p].d[0]-ql)+abs(t[p].d[1]-qr);
        if(d0<ans) ans=d0;
        if(t[p].l) dl=dist(t[p].l); else dl=inf;
        if(t[p].r) dr=dist(t[p].r); else dr=inf;
    
        if(dl<dr) {
        if(dl<ans) kd_query(t[p].l);
        if(dr<ans) kd_query(t[p].r);
        }
        else{
        if(dr<ans) kd_query(t[p].r);
        if(dl<ans) kd_query(t[p].l);
        }
    }
    
    inline void kd_insert(int now){
        int p=root,D=0;
        while(true){
        if(t[now].Max[0]>t[p].Max[0]) t[p].Max[0]=t[now].Max[0];
        if(t[now].Max[1]>t[p].Max[1]) t[p].Max[1]=t[now].Max[1];
        if(t[now].Min[0]<t[p].Min[0]) t[p].Min[0]=t[now].Min[0];
        if(t[now].Min[1]<t[p].Min[1]) t[p].Min[1]=t[now].Min[1];
    
        if(t[now].d[D]>=t[p].d[D]) {
            if(!t[p].r){
            t[p].r=now;
            return;
            }
            else p=t[p].r;
        }
        else{
            if(!t[p].l) {
            t[p].l=now;
            return ;
            }
            else p=t[p].l;
        }
    
        D=!D;
        }
    }
    
    int main()
    {
      n=getint();m=getint();
      for(int i=1;i<=n;i++) t[i].d[0]=getint(),t[i].d[1]=getint();
      root=kd_build(1,n,0);
    
      int x,y,z;
      for(int i=1;i<=m;i++) {
          x=getint(); y=getint(); z=getint();
          if(x==1) {
          n++;
          t[n].Max[0]=t[n].Min[0]=t[n].d[0]=y; t[n].Max[1]=t[n].Min[1]=t[n].d[1]=z;
          kd_insert(n);
          }
          else{
          ans=inf;
          ql=y,qr=z;
          kd_query(root);
          printf("%d
    ",ans);
          }
      }
      return 0;
    }
    View Code
  • 相关阅读:
    [LeetCode] Max Area of Island
    [TCP/IP] TCP数据报
    [LeetCode] Number of Islands
    [LeetCode] Binary Number with Alternating Bits
    [TCP/IP] Internet协议
    [LeetCode] Isomorphic Strings
    [LeetCode] Path Sum
    [LeetCode] Count and Say
    [学习OpenCV攻略][001][Ubuntu安装及配置]
    [国嵌攻略][038][时钟初始化]
  • 原文地址:https://www.cnblogs.com/Ketchum/p/13385419.html
Copyright © 2011-2022 走看看