【kd-tree】bzoj2648 SJY摆棋子
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 500001 #define INF 2147483647 #define KD 2//ά¶ÈÊý int qp[KD],disn; int n,root; bool dn; struct Node { int minn[KD],maxx[KD],p[KD]; int ch[2]; void Init() { for(int i=0;i<KD;++i) minn[i]=maxx[i]=p[i]; } int Dis() { int res=0; for(int i=0;i<KD;++i) { res+=max(0,minn[i]-qp[i]); res+=max(0,qp[i]-maxx[i]); } return res; } }T[N<<1]; void Update(int rt) { for(int i=0;i<2;++i) if(T[rt].ch[i]) for(int j=0;j<KD;++j) { T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]); T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]); } } int Abs(const int &x) { return x<0 ? (-x) : x; } int Dis(int a[],int b[]) { return Abs(a[0]-b[0])+Abs(a[1]-b[1]); } bool operator < (const Node &a,const Node &b) { return a.p[dn]!=b.p[dn] ? a.p[dn]<b.p[dn] : a.p[dn^1]<b.p[dn^1]; } int Buildtree(int l=1,int r=n,bool d=0) { dn=d; int m=(l+r>>1); nth_element(T+l,T+m,T+r+1); T[m].Init(); if(l!=m) T[m].ch[0]=Buildtree(l,m-1,d^1); if(m!=r) T[m].ch[1]=Buildtree(m+1,r,d^1); Update(m); return m; } void Query(int rt=root) { disn=min(disn,Dis(T[rt].p,qp)); int dd[2]; for(int i=0;i<2;i++) if(T[rt].ch[i]) dd[i]=T[T[rt].ch[i]].Dis(); else dd[i]=INF; bool f=(dd[0]<=dd[1]); if(dd[!f]<disn) Query(T[rt].ch[!f]); if(dd[f]<disn) Query(T[rt].ch[f]); } void Insert(int rt=root,bool d=0) { bool f=(T[n].p[d]>T[rt].p[d]); if(T[rt].ch[f]) Insert(T[rt].ch[f],d^1); else T[rt].ch[f]=n; Update(rt); } int q; int main() { // freopen("bzoj2716.in","r",stdin); // freopen("bzoj2716.out","w",stdout); int op,x,y; scanf("%d%d",&n,&q); for(int i=1;i<=n;++i) scanf("%d%d",&T[i].p[0],&T[i].p[1]); root=(1+n>>1); Buildtree(); for(int i=1;i<=q;++i) { scanf("%d",&op); if(op==1) { ++n; scanf("%d%d",&T[n].p[0],&T[n].p[1]); T[n].Init(); Insert(); } else { scanf("%d%d",&qp[0],&qp[1]); disn=INF; Query(); printf("%d\n",disn); } } return 0; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/