ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

kd-tree

2019-08-04 20:04:44  阅读:307  来源: 互联网

标签:wg kd int tree tr wen ww mx


纪念oi路上第一颗kd-tree

板子题

说说主要思想,考虑二叉搜索树来统计答案,玄学乱搞的地方就是减枝了。通过不断换维(不一定一直换,只要保证时间空间都尽量优就行),用<algorithm>库中的nth_element来找到中位数式的元素,此元素就是二叉搜索树对应的元素。最大值用A*思想减支,最小值用边界判断。还有值得学习的地方是判断先搜左儿子还是右儿子

/*
	从直系的直系的学长颓来的板子
*/
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cmath>
#define MAXN 100010
#define INF 0x7fffffff
using namespace std;
int opt;
struct ww{
	int wg[2];
	friend bool operator <(const ww &a,const ww &b){
		return a.wg[opt]<b.wg[opt];
	}
}wen[MAXN];
inline int minn(int a,int b){return a<b?a:b; }
inline int maxn(int a,int b){return a>b?a:b; }
int n;
struct KDTREE{
	int num,root,res;
	struct TREE{
		ww wen;
		int ls,rs;
		int mx[2],mn[2];
		#define ls(u) (tr[u].ls)
		#define rs(u) (tr[u].rs)
	}tr[MAXN];
	inline int mht(ww a,TREE b){
		return abs(a.wg[0]-b.wen.wg[0])+abs(a.wg[1]-b.wen.wg[1]); 
	}
	inline int mxdis(ww a,TREE b){
		int x=maxn(abs(a.wg[0]-b.mn[0]),abs(a.wg[0]-b.mx[0]));
		int y=maxn(abs(a.wg[1]-b.mn[1]),abs(a.wg[1]-b.mx[1]));
		return x+y;
	}
	inline int mndis(ww a,TREE b){//只减掉了在边界外的树枝
		int x=maxn(b.mn[0]-a.wg[0],0)+maxn(a.wg[0]-b.mx[0],0);
		int y=maxn(b.mn[1]-a.wg[1],0)+maxn(a.wg[1]-b.mx[1],0);
		return x+y;
	}
	void qw_mx(ww a,int u,int knd){
		if(!u)return ;int tmp;
		if((tmp=mht(a,tr[u]))>res)res=tmp;
		int lch=ls(u),rch=rs(u);
		if(a.wg[knd]<tr[lch].wen.wg[knd])swap(lch,rch);//
		if(mxdis(a,tr[lch])>res)qw_mx(a,lch,knd^1);
		if(mxdis(a,tr[rch])>res)qw_mx(a,rch,knd^1);
	}
	int qw_mx(ww a){
		res=-INF;
		qw_mx(a,root,0);
		return res;
	}
	void qw_mn(ww a,int u,int knd){
		//printf("u=%d knd=%d\n",u,knd);
		if(!u)return ;int tmp;
		if((tmp=mht(a,tr[u]))<res&&tmp)res=tmp;
		//cout<<tmp<<endl;
		int lch=ls(u),rch=rs(u);
		//cout<<lch<<" "<<rch<<endl;
		if(a.wg[knd]>tr[lch].wen.wg[knd])swap(lch,rch);//
		if(mndis(a,tr[lch])<res)qw_mn(a,lch,knd^1);
		if(mndis(a,tr[rch])<res)qw_mn(a,rch,knd^1);
	}
	int qw_mn(ww a){
		//cout<<a.wg[0]<<" "<<a.wg[1]<<endl;
		res=INF;
		qw_mn(a,root,0);
		//cout<<"STO"<<endl;
		return res;
	}
	void up(int u){
		if(ls(u))
			for(int i=0;i<2;++i){
				tr[u].mn[i]=minn(tr[u].mn[i],tr[ls(u)].mn[i]);
				tr[u].mx[i]=maxn(tr[u].mx[i],tr[ls(u)].mx[i]);
			}
		if(rs(u))
			for(int i=0;i<2;++i){
				tr[u].mn[i]=minn(tr[u].mn[i],tr[rs(u)].mn[i]);
				tr[u].mx[i]=maxn(tr[u].mx[i],tr[rs(u)].mx[i]);
			}
	}
	void build(int &u,int l,int r,int knd){
		if(r<l)return ;
		u=++num;opt=knd;
		int mid=l+r>>1;
		nth_element(wen+l,wen+mid,wen+r+1);
		tr[u].wen=wen[mid];
		for(int i=0;i<2;++i)
			tr[u].mn[i]=tr[u].mx[i]=wen[mid].wg[i];
		build(ls(u),l,mid-1,knd^1); 
		build(rs(u),mid+1,r,knd^1);
		up(u);
		//cout<<u<<" "<<tr[u].wen.wg[0]<<" "<<tr[u].wen.wg[1]<<endl;
		//cout<<tr[u].mn[0]<<" "<<tr[u].mn[1]<<" "<<tr[u].mx[0]<<" "<<tr[u].mx[1]<<endl;
	}
	void build(){
		root=num=0;
		build(root,1,n,0);
	}
}QwQ;
int ans=INF;
int main(){
//	freopen("da.in","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
		scanf("%d%d",&wen[i].wg[0],&wen[i].wg[1]);
	QwQ.build();
	for(int i=1;i<=n;++i){
		ans=minn(ans,QwQ.qw_mx(wen[i])-QwQ.qw_mn(wen[i]));
		//cout<<"HHHHHHHHH"<<QwQ.qw_mx(wen[i])<<" "<<QwQ.qw_mn(wen[i])<<endl;
	}
	printf("%d\n",ans);
}

 

标签:wg,kd,int,tree,tr,wen,ww,mx
来源: https://www.cnblogs.com/2018hzoicyf/p/11299423.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有