K-D tree 重学
仍然依旧是粘板子
code
#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=5e5+5;
int n,comp;
int minn[N],maxn[N],ans;
struct POT{
int d[2],id;
bool operator < (POT a)const{
return a.d[comp]>d[comp];
}
}sca[N];
int DIS(POT x,POT y){
return abs(x.d[0]-y.d[0])+abs(x.d[1]-y.d[1]);
}
struct KD_TREE{
struct KD_POT{
POT x;
int ls,rs;
int mn[2],mx[2];
}tr[N];
int rt,seg;
POT res;
void pushup(int x){
int ls=tr[x].ls,rs=tr[x].rs;
for(re i=0;i<=1;i++){
tr[x].mn[i]=tr[x].mx[i]=tr[x].x.d[i];
if(ls){
tr[x].mn[i]=min(tr[x].mn[i],tr[ls].mn[i]);
tr[x].mx[i]=max(tr[x].mx[i],tr[ls].mx[i]);
}
if(rs){
tr[x].mn[i]=min(tr[x].mn[i],tr[rs].mn[i]);
tr[x].mx[i]=max(tr[x].mx[i],tr[rs].mx[i]);
}
}
}
void build(int &x,int l,int r,int f){
int mid=l+r>>1;
comp=f;
nth_element(sca+l,sca+mid,sca+r+1);
x=++seg;
tr[x].x=sca[mid];
if(l<mid)build(tr[x].ls,l,mid-1,f^1);
if(r>mid)build(tr[x].rs,mid+1,r,f^1);
pushup(x);return ;
}
int get_max(int x,POT y){
int ret=0;
for(re i=0;i<=1;i++){
ret+=max(abs(y.d[i]-tr[x].mn[i]),abs(tr[x].mx[i]-y.d[i]));
}
return ret;
}
int get_min(int x,POT y){
int ret=0;
for(re i=0;i<=1;i++){
//int tmp=min(abs(y.d[i]-tr[x].mn[i]),abs(tr[x].mx[i]-y.d[i]));
ret+=max(tr[x].mn[i]-y.d[i],0);
ret+=max(y.d[i]-tr[x].mx[i],0);
}
return ret;
}
void query_max(int x,POT y){
if(!x)return ;
if(DIS(tr[x].x,y)>maxn[y.id]&&tr[x].x.id!=y.id){
maxn[y.id]=DIS(tr[x].x,y);
res=tr[x].x;
}
int ls=tr[x].ls,rs=tr[x].rs,dl=0,dr=0;
if(ls)dl=get_max(ls,y);
if(rs)dr=get_max(rs,y);
if(dl>dr){
if(dl>maxn[y.id])query_max(ls,y);
if(dr>maxn[y.id])query_max(rs,y);
}
else{
if(dr>maxn[y.id])query_max(rs,y);
if(dl>maxn[y.id])query_max(ls,y);
}
return ;
}
void query_min(int x,POT y){
if(!x)return ;
if(DIS(tr[x].x,y)<minn[y.id]&&tr[x].x.id!=y.id){
minn[y.id]=DIS(tr[x].x,y);
res=tr[x].x;
}
int ls=tr[x].ls,rs=tr[x].rs,dl=0x3f3f3f3f,dr=0x3f3f3f3f;
if(ls)dl=get_min(ls,y);
if(rs)dr=get_min(rs,y);
if(dl<dr){
if(dl<minn[y.id])query_min(ls,y);
if(dr<minn[y.id])query_min(rs,y);
}
else{
if(dr<minn[y.id])query_min(rs,y);
if(dl<minn[y.id])query_min(ls,y);
}
return ;
}
}kd;
signed main(){
scanf("%d",&n);
for(re i=1;i<=n;i++){
scanf("%d%d",&sca[i].d[0],&sca[i].d[1]),sca[i].id=i;
}
memset(minn,0x7f,sizeof(minn));
kd.build(kd.rt,1,n,0);
ans=0x3f3f3f3f;
for(re i=1;i<=n;i++){
kd.query_max(kd.rt,sca[i]);
maxn[kd.res.id]=maxn[sca[i].id];
kd.query_min(kd.rt,sca[i]);
minn[kd.res.id]=minn[sca[i].id];
ans=min(ans,maxn[sca[i].id]-minn[sca[i].id]);
}
printf("%d",ans);
}
code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*t;
}
const int inf=0x3f3f3f3f;
const int N=1e6+5;
const double al=0.7;
int n,m,comp;
struct P{int d[2];P(){}P(int x,int y){d[0]=x;d[1]=y;}}sca[N];
bool com(P a,P b){return a.d[comp]<b.d[comp];}
int dis(P a,P b){return abs(a.d[0]-b.d[0])+abs(a.d[1]-b.d[1]);}
struct KD{
struct POT{
P x;int ls,rs,siz;
int mn[2],mx[2];
}tr[N];
int rt,seg,res,ji[N],cnt;
void pushup(int x){
tr[x].siz=tr[tr[x].ls].siz+tr[tr[x].rs].siz+1;
fo(i,0,1){
tr[x].mn[i]=tr[x].mx[i]=tr[x].x.d[i];
if(tr[x].ls){
tr[x].mn[i]=min(tr[x].mn[i],tr[tr[x].ls].mn[i]);
tr[x].mx[i]=max(tr[x].mx[i],tr[tr[x].ls].mx[i]);
}
if(tr[x].rs){
tr[x].mn[i]=min(tr[x].mn[i],tr[tr[x].rs].mn[i]);
tr[x].mx[i]=max(tr[x].mx[i],tr[tr[x].rs].mx[i]);
}
}
}
void clear(int x){
tr[x].ls=tr[x].rs=0;tr[x].siz=1;
tr[x].mn[0]=tr[x].mx[0]=tr[x].x.d[0];
tr[x].mn[1]=tr[x].mx[1]=tr[x].x.d[1];
}
void build(int &x,int l,int r,int f){
int mid=l+r>>1;x=ji[mid];comp=f;
nth_element(sca+l,sca+mid,sca+r+1,com);
tr[x].x=sca[mid];pushup(x);
if(l<mid)build(tr[x].ls,l,mid-1,f^1);
if(r>mid)build(tr[x].rs,mid+1,r,f^1);
pushup(x);return ;
}
void pia(int x){
ji[++cnt]=x;sca[cnt]=tr[x].x;
if(tr[x].ls)pia(tr[x].ls);
if(tr[x].rs)pia(tr[x].rs);
}
bool need(int x){
if(tr[tr[x].ls].siz>tr[x].siz*al)return true;
if(tr[tr[x].rs].siz>tr[x].siz*al)return true;
return false;
}
void ins(int &x,int f,P v){
if(!x){
x=++seg;tr[x].x=v;
pushup(x);return ;
}
if(v.d[f]<=tr[x].x.d[f])ins(tr[x].ls,f^1,v);
else ins(tr[x].rs,f^1,v);
if(need(x)){cnt=0;pia(x);build(x,1,cnt,f);}
pushup(x);return ;
}
int get_min(int x,P v){
int ret=0;
fo(i,0,1){
ret+=max(tr[x].mn[i]-v.d[i],0);
ret+=max(v.d[i]-tr[x].mx[i],0);
}
return ret;
}
void query(int x,P v){
if(!x)return ;
if(dis(tr[x].x,v)<res)res=dis(tr[x].x,v);
int dl=inf,dr=inf;
if(tr[x].ls)dl=get_min(tr[x].ls,v);
if(tr[x].rs)dr=get_min(tr[x].rs,v);
if(dl<dr){
if(dl<res)query(tr[x].ls,v);
if(dr<res)query(tr[x].rs,v);
}
else{
if(dr<res)query(tr[x].rs,v);
if(dl<res)query(tr[x].ls,v);
}
}
}kd;
signed main(){
kd.seg=n=read();m=read();
fo(i,1,n)sca[i].d[0]=read(),sca[i].d[1]=read(),kd.ji[i]=i;
kd.build(kd.rt,1,n,0);
fo(i,1,m){
int tp=read(),x=read(),y=read();
if(tp==1)kd.ins(kd.rt,0,P(x,y));
else {
kd.res=inf;kd.query(kd.rt,P(x,y));
printf("%d\n",kd.res);
}
}
}