zoukankan      html  css  js  c++  java
  • 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
    ",kd.query(point(x,y)));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    转:线程Thread (1)
    jquery 比较全面的API中文版地址
    IE 出现stack overflow 报错的原因归纳
    转:C#常用的集合类型(ArrayList类、Stack类、Queue类、Hashtable类、Sort)
    转:双向链表dblinklist
    转:stack
    转:queue
    解决获取同胞元素空白节点影响的问题
    取10到100的随机数方法
    进度条
  • 原文地址:https://www.cnblogs.com/Stump/p/9191296.html
Copyright © 2011-2022 走看看