Bzoj 2648 KD-Tree

信仰剪枝喜+1

#include <bits/stdc++.h>
using namespace std;
const int INF=1e9+7;
struct node{
    int d[2],ma[2],mi[2],l,r;
}T[1000003];
int rt,n,m,cmp_d;
inline 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^1] < b.d[cmp_d^1];
}
inline void up(int u,int v){
    T[u].ma[0]=max(T[u].ma[0],T[v].ma[0]);
    T[u].ma[1]=max(T[u].ma[1],T[v].ma[1]);
    T[u].mi[0]=min(T[u].mi[0],T[v].mi[0]);
    T[u].mi[1]=min(T[u].mi[1],T[v].mi[1]);
}
inline int build(int l,int r,int D){
    int mid=(l+r)>>1;
    cmp_d=D;
    nth_element(T+l,T+mid,T+r+1,cmp);
    T[mid].ma[0]=T[mid].mi[0]=T[mid].d[0];
    T[mid].ma[1]=T[mid].mi[1]=T[mid].d[1];
    if(l!=mid){
        T[mid].l=build(l,mid-1,D^1);
        up(mid,T[mid].l);
    }
    if(r!=mid){
        T[mid].r=build(mid+1,r,D^1);
        up(mid,T[mid].r);
    }
    return mid;
}
inline void insert(int k){
    int p=rt;
    int D=0;
    while(1){
        up(p,k);
        if(T[k].d[D]<=T[p].d[D]){
            if(!T[p].l){
                T[p].l=k;
                return ;
            }
            p=T[p].l;
        }
        else {
            if(!T[p].r){
                T[p].r=k;
                return ;
            }
            p=T[p].r;
        }
        D^=1;
    }
}
int ans;
int x,y;
//估计范围
inline int getdis(int p){
    int ret=0;
    if(x>T[p].ma[0])ret+=x-T[p].ma[0];
    if(x<T[p].mi[0])ret+=T[p].mi[0]-x;
    if(y>T[p].ma[1])ret+=y-T[p].ma[1];
    if(y<T[p].mi[1])ret+=T[p].mi[1]-y;
    return ret;
}
inline void query(int p){
    int d0=abs(x-T[p].d[0])+abs(y-T[p].d[1]);
    if(d0<ans)ans=d0;
    int dl=INF,dr=INF;
    if(T[p].l)dl=getdis(T[p].l);
    if(T[p].r)dr=getdis(T[p].r);
    if(dl<dr){
        if(dl<ans)query(T[p].l);
        if(dr<ans)query(T[p].r);
    }
    else {
        if(dr<ans)query(T[p].r);
        if(dl<ans)query(T[p].l);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&T[i].d[0],&T[i].d[1]);
    }
    rt=build(1,n,0);
    for(int i=1;i<=m;i++){
        int tag;
        scanf("%d%d%d",&tag,&x,&y);
        if(tag==1){
            n++;
            T[n].d[0]=T[n].ma[0]=T[n].mi[0]=x;
            T[n].d[1]=T[n].ma[1]=T[n].mi[1]=y;
            insert(n);
        }
        else {
            ans=INF;
            query(rt);
            printf("%d\n",ans);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/MrBird_to_fly/article/details/80869431