突然发现 SCOI之前我tm刷的基本都是SDOI 的题…
kd-tree板子题…
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{
x = 0;char c;int sign = 1;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
const int N = 5e5 + 500;
int t,n;
struct Point { int x[2]; }p[N];
const bool cmp(Point a,Point b) { return a.x[t] < b.x[t]; }
struct KD_tree
{
int ymx[N],ymi[N],xmx[N],xmi[N];
int l[N],r[N],mx,mi,P;
inline void update(int x)
{
if(l[x])
{
xmx[x] = max(xmx[l[x]],xmx[x]);
ymx[x] = max(ymx[l[x]],ymx[x]);
xmi[x] = min(xmi[l[x]],xmi[x]);
ymi[x] = min(ymi[l[x]],ymi[x]);
}
if(r[x])
{
xmx[x] = max(xmx[r[x]],xmx[x]);
ymx[x] = max(ymx[r[x]],ymx[x]);
xmi[x] = min(xmi[r[x]],xmi[x]);
ymi[x] = min(ymi[r[x]],ymi[x]);
}
}
int build(int L,int R)
{
if(R < L) return 0;
int mid = L + R >> 1;
nth_element(p + L,p + mid,p + R + 1,cmp);
xmx[mid] = xmi[mid] = p[mid].x[0];
ymx[mid] = ymi[mid] = p[mid].x[1];
if(L == R) return L;
t ^= 1;
l[mid] = build(L,mid - 1);
r[mid] = build(mid + 1,R);
update(mid);
return mid;
}
inline int gmx(int x) { return max(abs(xmx[x] - p[P].x[0]),abs(xmi[x] - p[P].x[0])) + max(abs(ymx[x] - p[P].x[1]),abs(ymi[x] - p[P].x[1])); }
inline int gmi(int x)
{
return max(xmi[x] - p[P].x[0],0) + max(p[P].x[0] - xmx[x],0) +
max(ymi[x] - p[P].x[1],0) + max(p[P].x[1] - ymx[x],0);
}
void qmax(int x)
{
if(!x) return;
if(x != P) mx = max(mx,abs(p[x].x[0] - p[P].x[0]) + abs(p[x].x[1] - p[P].x[1]));
int dl = gmx(l[x]),dr = gmx(r[x]);
if(dl < dr)
{
if(dr > mx) qmax(r[x]);
if(dl > mx) qmax(l[x]);
}
else
{
if(dl > mx) qmax(l[x]);
if(dr > mx) qmax(r[x]);
}
}
void qmin(int x)
{
if(!x) return;
if(x != P) mi = min(mi,abs(p[x].x[0] - p[P].x[0]) + abs(p[x].x[1] - p[P].x[1]));
int dl = gmi(l[x]),dr = gmi(r[x]);
if(dl > dr)
{
if(dr < mi) qmin(r[x]);
if(dl < mi) qmin(l[x]);
}
else
{
if(dl < mi) qmin(l[x]);
if(dr < mi) qmin(r[x]);
}
}
}tree;
int main()
{
read(n);
rep(i,1,n) read(p[i].x[0]),read(p[i].x[1]);
tree.build(1,n);
int rt = 1 + n >> 1,ans = 1e9+7;
rep(i,1,n)
{
tree.P = i;tree.mx = 0;tree.mi = 1e9 + 7;
tree.qmax(rt);tree.qmin(rt);
ans = min(ans,tree.mx - tree.mi);
}
cout << ans << endl;
return 0;
}