题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648
学习资料:https://blog.****.net/zhl30041839/article/details/9277807
https://www.cnblogs.com/galaxies/p/kdtree.html
模仿代码:https://blog.****.net/lych_cys/article/details/50809141
那个求点到块的距离的方法挺妙的。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
int const xn=5e5+,inf=1e9;
int n,m,rt,cnt,dm,c[xn<<][],ans;
struct N{int mn[],mx[],p[];}a[xn],t[xn<<];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int Min(int x,int y){return x<y?x:y;}
int Max(int x,int y){return x<y?y:x;}
int Abs(int x){return x>?x:-x;}
bool cmp(N a,N b){return a.p[dm]<b.p[dm];}
void turn(int x,N y){for(int i=;i<;i++)t[x].mn[i]=t[x].mx[i]=t[x].p[i]=y.p[i];}
void pushup(int x)
{
int ls=c[x][],rs=c[x][];
for(int i=;i<;i++)
{
if(ls)t[x].mn[i]=Min(t[x].mn[i],t[ls].mn[i]),t[x].mx[i]=Max(t[x].mx[i],t[ls].mx[i]);
if(rs)t[x].mn[i]=Min(t[x].mn[i],t[rs].mn[i]),t[x].mx[i]=Max(t[x].mx[i],t[rs].mx[i]);
}
}
void build(int &x,int l,int r,int nw)
{
x=++cnt; dm=nw;
nth_element(a+l,a+mid,a+r+,cmp);
turn(x,a[mid]);
if(mid>l)build(c[x][],l,mid-,nw^);
if(mid<r)build(c[x][],mid+,r,nw^);
pushup(x);
}
void ins(int x,N v,int nw)
{
if(v.p[nw]<=t[x].p[nw])
{
if(c[x][])ins(c[x][],v,nw^);
else c[x][]=++cnt,turn(c[x][],v);
}
else
{
if(c[x][])ins(c[x][],v,nw^);
else c[x][]=++cnt,turn(c[x][],v);
}
pushup(x);
}
int dis(int x,N y)
{
int ret=;
for(int i=;i<;i++)
ret+=Max(,t[x].mn[i]-y.p[i]),ret+=Max(,y.p[i]-t[x].mx[i]);
return ret;
}
int query(int x,N v)
{
ans=min(ans,Abs(t[x].p[]-v.p[])+Abs(t[x].p[]-v.p[]));
int d1=(c[x][]?dis(c[x][],v):inf),d2=(c[x][]?dis(c[x][],v):inf);
if(d1<=d2){if(d1<ans)query(c[x][],v); if(d2<ans)query(c[x][],v);}
else {if(d2<ans)query(c[x][],v); if(d1<ans)query(c[x][],v);}
}
int main()
{
n=rd(); m=rd(); N tmp;
for(int i=;i<=n;i++)a[i].p[]=rd(),a[i].p[]=rd();
build(rt,,n,);
for(int i=,op;i<=m;i++)
{
op=rd(); tmp.p[]=rd(); tmp.p[]=rd();
if(op==)ins(rt,tmp,);
else ans=inf,query(rt,tmp),printf("%d\n",ans);
}
return ;
}