1. [BZOJ]1941: [Sdoi2010]Hide and Seek
题目大意:给出n个二维平面上的点,一个点的权值是它到其他点的最长距离减最短距离,距离为曼哈顿距离,求最小权值。(n<=500,000)
思路:k-d tree裸题。
#include<cstdio> #include<algorithm> using namespace std; inline int read() { int x;char c; while((c=getchar())<‘0‘||c>‘9‘); for(x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;)x=(x<<3)+(x<<1)+c-‘0‘; return x; } #define MN 500000 #define INF 0x7FFFFFFF int rt,D,q[2]; struct node { int p[2],mn[2],mx[2],l,r; friend bool operator<(const node&a,const node&b){return a.p[D]<b.p[D];} }t[MN+5]; void up(int k) { for(int l=t[k].l,r=t[k].r,i=0;i<2;++i) t[k].mn[i]=t[k].mx[i]=t[k].p[i], l?(t[k].mn[i]=min(t[k].mn[i],t[l].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[l].mx[i])):0, r?(t[k].mn[i]=min(t[k].mn[i],t[r].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[r].mx[i])):0; } int build(int l,int r) { if(l>r)return 0; int mid=l+r>>1; nth_element(t+l,t+mid,t+r+1); D^=1;t[mid].l=build(l,mid-1);D^=1; D^=1;t[mid].r=build(mid+1,r);D^=1; return up(mid),mid; } inline int calmx(int k) { return max(abs(q[0]-t[k].mn[0]),abs(t[k].mx[0]-q[0]))+ max(abs(q[1]-t[k].mn[1]),abs(t[k].mx[1]-q[1])); } void qmx(int k) { D=max(D,abs(t[k].p[0]-q[0])+abs(t[k].p[1]-q[1])); int dl=t[k].l?calmx(t[k].l):-INF,dr=t[k].r?calmx(t[k].r):-INF; if(dl>dr){if(dl>D)qmx(t[k].l);if(dr>D)qmx(t[k].r);} else{if(dr>D)qmx(t[k].r);if(dl>D)qmx(t[k].l);} } inline int calmn(int k) { return max(t[k].mn[0]-q[0],0)+max(q[0]-t[k].mx[0],0)+ max(t[k].mn[1]-q[1],0)+max(q[1]-t[k].mx[1],0); } void qmn(int k) { int x=abs(t[k].p[0]-q[0])+abs(t[k].p[1]-q[1]);if(x)D=min(D,x); int dl=t[k].l?calmn(t[k].l):INF,dr=t[k].r?calmn(t[k].r):INF; if(dl<dr){if(dl<D)qmn(t[k].l);if(dr<D)qmn(t[k].r);} else{if(dr<D)qmn(t[k].r);if(dl<D)qmn(t[k].l);} } int main() { int n=read(),i,x,ans=INF; for(i=1;i<=n;++i)t[i].p[0]=read(),t[i].p[1]=read(); rt=build(1,n); for(i=1;i<=n;++i) { q[0]=t[i].p[0];q[1]=t[i].p[1]; D=-INF;qmx(rt);x=D; D=INF;qmn(rt); ans=min(ans,x-D); } printf("%d",ans); }
时间: 2024-09-29 04:43:47