洛谷P2479 [SDOI2010] 捉迷藏
#include <bits/stdc++.h>
#define Min(_A, _B) (_A < _B ? _A : _B)
#define Max(_A, _B) (_A > _B ? _A : _B)
#define Abs(_A) (_A > 0 ? _A : -(_A))
struct pair{ int x, y; } a[500010];
struct KD_Tree{ int xmin, xmax, ymin, ymax, myx, myy; KD_Tree *l, *r; } b[1 << 22], *rt = b; int tot;
bool vis[1 << 22];
int N, lim;
bool cmp1(const pair &i, const pair &j){ return i.x < j.x; }
bool cmp2(const pair &i, const pair &j){ return i.y < j.y; }
void Build(KD_Tree *&u, int Ls, int Rs, int s)
{
u = b + ++tot; *u = b[0];
int Mid = Ls + Rs >> 1;
if(s & 1) std::nth_element(a + Ls, a + Mid, a + Rs + 1, cmp1);
else std::nth_element(a + Ls, a + Mid, a + Rs + 1, cmp2);
if(Ls < Mid) Build(u->l, Ls, Mid - 1, s ^ 1);
if(Rs > Mid) Build(u->r, Mid + 1, Rs, s ^ 1);
u->myx = a[Mid].x; u->myy = a[Mid].y;
u->xmin = Min(u->l->xmin, u->r->xmin);
u->xmax = Max(u->l->xmax, u->r->xmax);
u->xmin = Min(u->xmin, u->myx);
u->xmax = Max(u->xmax, u->myx);
u->ymin = Min(u->l->ymin, u->r->ymin);
u->ymax = Max(u->l->ymax, u->r->ymax);
u->ymin = Min(u->ymin, u->myy);
u->ymax = Max(u->ymax, u->myy);
}
int Get_Min(KD_Tree *u, int p)
{
int dis = 0;
if(u->xmin >= a[p].x) dis += u->xmin - a[p].x;
if(u->xmax <= a[p].x) dis += a[p].x - u->xmax;
if(u->ymin >= a[p].y) dis += u->ymin - a[p].y;
if(u->ymax <= a[p].y) dis += a[p].y - u->ymax;
return dis;
}
int Get_Max(KD_Tree *u, int p)
{
int dis = 0;
dis += Max(Abs(a[p].x - u->xmin), Abs(u->xmax - a[p].x));
dis += Max(Abs(a[p].y - u->ymin), Abs(u->ymax - a[p].y));
return dis;
}
void Query_Min(KD_Tree *u, int p)
{
int t = Abs(a[p].x - u->myx) + Abs(a[p].y - u->myy);
if(t) lim = Min(lim, t);
if(lim <= Get_Min(u, p)) return ;
if(u->l != b && u->r != b && Get_Min(u->l, p) > Get_Min(u->r, p)) std::swap(u->l, u->r);
if(u->l != b) Query_Min(u->l, p);
if(u->r != b) Query_Min(u->r, p);
}
void Query_Max(KD_Tree *u, int p)
{
int t = Abs(a[p].x - u->myx) + Abs(a[p].y - u->myy);
if(t) lim = Max(lim, t);
if(lim >= Get_Max(u, p)) return ;
if(u->l != b && u->r != b && Get_Max(u->l, p) < Get_Max(u->r, p)) std::swap(u->l, u->r);
if(u->l != b) Query_Max(u->l, p);
if(u->r != b) Query_Max(u->r, p);
}
int main()
{
b[0] = (KD_Tree){2147483647, 0, 2147483647, 0, 0, 0, b, b};
scanf("%d", &N);
for(int i = 1; i <= N; ++i) scanf("%d %d", &a[i].x, &a[i].y);
Build(rt, 1, N, 0);
int ans = 2147483647;
for(int i = 1; i <= N; ++i)
{
int tmp = 0;
lim = 2147483647; Query_Min(rt, i); tmp -= lim;
lim = 0; Query_Max(rt, i); tmp += lim;
ans = Min(tmp, ans);
}
printf("%d\n", ans);
return 0;
}