【kd-tree】bzoj2716 [Violet 3]天使玩偶

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 500001
#define INF 2147483647
#define KD 2//ά¶ÈÊý
int qp[KD],disn;
int n,root;
bool dn;
struct Node
{
    int minn[KD],maxx[KD],p[KD];
    int ch[2];
    void Init()
      {
        for(int i=0;i<KD;++i)
          minn[i]=maxx[i]=p[i];
      }
    int Dis()
      {
        int res=0;
        for(int i=0;i<KD;++i)
          {
            res+=max(0,minn[i]-qp[i]);
            res+=max(0,qp[i]-maxx[i]);
          }
        return res;
      }
}T[N<<1];
void Update(int rt)
{
    for(int i=0;i<2;++i)
      if(T[rt].ch[i])
        for(int j=0;j<KD;++j)
          {
            T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
            T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
          }
}
int Abs(const int &x)
{
    return x<0 ? (-x) : x;
}
int Dis(int a[],int b[])
{
    return Abs(a[0]-b[0])+Abs(a[1]-b[1]);
}
bool operator < (const Node &a,const Node &b)
{
    return a.p[dn]!=b.p[dn] ? a.p[dn]<b.p[dn] : a.p[dn^1]<b.p[dn^1];
}
int Buildtree(int l=1,int r=n,bool d=0)
{
    dn=d;
    int m=(l+r>>1);
    nth_element(T+l,T+m,T+r+1);
    T[m].Init();
    if(l!=m) T[m].ch[0]=Buildtree(l,m-1,d^1);
    if(m!=r) T[m].ch[1]=Buildtree(m+1,r,d^1);
    Update(m);
    return m;
}
void Query(int rt=root)
{
    disn=min(disn,Dis(T[rt].p,qp));
    int dd[2];
    for(int i=0;i<2;i++)
      if(T[rt].ch[i])
        dd[i]=T[T[rt].ch[i]].Dis();
      else dd[i]=INF;
    bool f=(dd[0]<=dd[1]);
    if(dd[!f]<disn) Query(T[rt].ch[!f]);
    if(dd[f]<disn) Query(T[rt].ch[f]);
}
void Insert(int rt=root,bool d=0)
{
    bool f=(T[n].p[d]>T[rt].p[d]);
    if(T[rt].ch[f])
      Insert(T[rt].ch[f],d^1);
    else
      T[rt].ch[f]=n;
    Update(rt);
}
int q;
int main()
{
//  freopen("bzoj2716.in","r",stdin);
//  freopen("bzoj2716.out","w",stdout);
    int op,x,y;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i)
      scanf("%d%d",&T[i].p[0],&T[i].p[1]);
    root=(1+n>>1);
    Buildtree();
    for(int i=1;i<=q;++i)
      {
        scanf("%d",&op);
        if(op==1)
          {
            ++n;
            scanf("%d%d",&T[n].p[0],&T[n].p[1]);
            T[n].Init();
            Insert();
          }
        else
          {
            scanf("%d%d",&qp[0],&qp[1]);
            disn=INF;
            Query();
            printf("%d
",disn);
          }
      }
    return 0;
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/4587137.html