kd-tree板子
https://www.lydsy.com/JudgeOnline/problem.php?id=2648
存个kd-tree板子
#include<cstdio> #include<algorithm> #include<cmath> #define gi(x) read(x) #define gii(x,y) gi(x),gi(y) #define giii(x,y,z) gii(x,y),gi(z) #define inf 1000000000 #define re register #define rep(i,s,t) for(re int i=s;i<=t;++i) using namespace std; typedef long long ll; const int N=5e5+11; int n,m,rt,D; namespace IO{ #define gc getchar() #define pc(x) putchar(x) template<typename T>inline void read(T &x){ x=0;int f=1;char ch=gc;while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gc;} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=gc;x*=f;return; } template<typename T>inline void write(T x=0){ T wr[51];wr[0]=0;if(x<0)pc('-'),x=-x;if(!x)pc(48); while(x)wr[++wr[0]]=x%10,x/=10;while(wr[0])pc(48+wr[wr[0]--]);return; } } using IO::read; using IO::write; struct point{ int d[2],mn[2],mx[2],l,r; inline int &operator[](const int x){ return d[x]; } inline void in(){ gii(d[0],d[1]); } point(int x=0,int y=0){ l=r=0,d[0]=x,d[1]=y; } friend inline bool operator<(point a,point b){ return a[D]<b[D]; } }p[N]; inline int dis(point a,point b){ return fabs(a[0]-b[0])+fabs(a[1]-b[1]); } struct kd_tree{ int ans; point t[N+N],T; inline void up(int k){ point l=t[t[k].l],r=t[t[k].r]; rep(i,0,1){ 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]); } } inline 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][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); up(mid); return mid; } inline int get(int k,point p){ int tmp=0; rep(i,0,1)tmp+=max(0,t[k].mn[i]-p[i]); rep(i,0,1)tmp+=max(0,p[i]-t[k].mx[i]); return tmp; } inline void insert(int k,int now){ if(T[now]>=t[k][now]){ if(t[k].r)insert(t[k].r,now^1); else{ t[k].r=++n;t[n]=T; rep(i,0,1) t[n].mn[i]=t[n].mx[i]=t[n][i]; } } else{ if(t[k].l)insert(t[k].l,now^1); else{ t[k].l=++n;t[n]=T; rep(i,0,1) t[n].mn[i]=t[n].mx[i]=t[n][i]; } } up(k); } inline void query(int k,int now){ int d,dl=inf,dr=inf; d=dis(t[k],T); ans=min(ans,d); if(t[k].l)dl=get(t[k].l,T); if(t[k].r)dr=get(t[k].r,T); if(dl<dr){ if(dl<ans)query(t[k].l,now^1); if(dr<ans)query(t[k].r,now^1); } else{ if(dr<ans)query(t[k].r,now^1); if(dl<ans)query(t[k].l,now^1); } } inline int query(point p){ ans=inf,T=p,query(rt,0); return ans; } inline void insert(point p){ T=p,insert(rt,0); } }kd; int main(){ gii(n,m); rep(i,1,n) p[i].in(); rt=kd.build(1,n,0); for(int op,x,y;m--;){ giii(op,x,y); if(op==1)kd.insert(point(x,y)); else printf("%d\n",kd.query(point(x,y))); } return 0; }