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;
}

  

猜你喜欢

转载自www.cnblogs.com/Stump/p/9191296.html