题目链接:1941:[Sdoi2010]Hide and Seek
和上一个题一样是个模板题QwQ
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for (int i=x;i<=y;++i)
using namespace std;
const int maxn=500010;
const int inf=0x7fffffff/2-1;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,ANSWER,D,root;
int x[maxn],y[maxn];
struct point{
int d[2],mn[2],mx[2],l,r;
point(int x=0,int y=0){
l=0,r=0; d[0]=x,d[1]=y;
}
}p[maxn];
bool operator < (const point &a,const point &b){
return a.d[D]<b.d[D];
}
int dis(point a,point b){
return abs(a.d[0]-b.d[0])+abs(a.d[1]-b.d[1]);
}
struct k_d_tree{
int ans;
point t[maxn],T;
void update(int k){
point l=t[t[k].l],r=t[t[k].r];
rep(i,0,1){
t[k].mn[i]=t[k].mx[i]=t[k].d[i];
if (t[k].l) t[k].mn[i]=min(t[k].mn[i],l.mn[i]),
t[k].mx[i]=max(t[k].mx[i],l.mx[i]);
if (t[k].r) t[k].mn[i]=min(t[k].mn[i],r.mn[i]),
t[k].mx[i]=max(t[k].mx[i],r.mx[i]);
}
}
int build(int l,int r,int now){
D=now;int mid=(l+r)>>1;
nth_element(p+l,p+mid,p+r+1);
t[mid]=p[mid];
rep(i,0,1) t[mid].mn[i]=t[mid].mx[i]=t[mid].d[i];
if (l<mid) t[mid].l=build(l,mid-1,now^1);
if (mid<r) t[mid].r=build(mid+1,r,now^1);
update(mid); return mid;
}
int getdis1(int k){
int ret=0;
rep(i,0,1) ret+=max(t[k].mn[i]-T.d[i],0);
rep(i,0,1) ret+=max(T.d[i]-t[k].mx[i],0);
return ret;
}
int getdis2(point a){
int ret=0;
rep(i,0,1) ret+=max(abs(T.d[i]-a.mn[i]),abs(T.d[i]-a.mx[i]));
return ret;
}
void askmn(int k){
int d,dl=inf,dr=inf;
d=dis(t[k],T); if(d)ans=min(ans,d);
if (t[k].l) dl=getdis1(t[k].l);
if (t[k].r) dr=getdis1(t[k].r);
if (dl<dr){
if (dl<ans) askmn(t[k].l);
if (dr<ans) askmn(t[k].r);
}else{
if (dr<ans) askmn(t[k].r);
if (dl<ans) askmn(t[k].l);
}
}
void askmx(int k){
int d,dl=-inf,dr=-inf;
d=dis(t[k],T); ans=max(ans,d);
if (t[k].l) dl=getdis2(t[t[k].l]);
if (t[k].r) dr=getdis2(t[t[k].r]);
if (dl>dr){
if (dl>ans) askmx(t[k].l);
if (dr>ans) askmx(t[k].r);
}else{
if (dr>ans) askmx(t[k].r);
if (dl>ans) askmx(t[k].l);
}
}
int query2(point p){
T=p; ans=-inf;
askmx(root); return ans;
}
int query1(point p){
T=p; ans=inf;
askmn(root); return ans;
}
}kdt;
int main(){
n=read();
rep(i,1,n){
x[i]=read(); y[i]=read();
p[i].d[0]=x[i]; p[i].d[1]=y[i];
}
root=kdt.build(1,n,0);
ANSWER=inf;
rep(i,1,n){
int tmp1=kdt.query1(point(x[i],y[i]));
int tmp2=kdt.query2(point(x[i],y[i]));
ANSWER=min(ANSWER,tmp2-tmp1);
}
printf("%d\n",ANSWER);
}