BZOJ 1941 Sdoi2010 Hide and Seek K-Dimensional-Tree

题目大意:给定平面上的n个点,定义距离为曼哈顿距离,求一个点到其他所有点的最大距离与最小距离之差最小

KDTree……这东西好神啊

注意计算最小距离的时候不能把自己也算进去= =

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 500500
#define INF 0x3f3f3f3f
using namespace std;
struct Point{
	int x,y;
	Point() {}
	Point(int _,int __):
		x(_),y(__) {}
	friend istream& operator >> (istream &_,Point &p)
	{
		scanf("%d%d",&p.x,&p.y);
		return _;
	}
	friend bool operator != (const Point &p1,const Point &p2)
	{
		return p1.x!=p2.x || p1.y!=p2.y ;
	}
	friend int Distance(const Point &p1,const Point &p2)
	{
		return abs(p1.x-p2.x) + abs(p1.y-p2.y);
	}
}points[M];
int n,ans=INF;
bool Compare_x(const Point &p1,const Point &p2)
{
	return p1.x < p2.x;
}
bool Compare_y(const Point &p1,const Point &p2)
{
	return p1.y < p2.y;
}
namespace K_Dimension_Tree{
	struct abcd{
		abcd *ls,*rs;
		Point p;
		int x1,y1,x2,y2;
		abcd() {}
		abcd(const Point &_):p(_)
		{
			x1=x2=p.x;
			y1=y2=p.y;
		}
		void Push_Up(abcd *x)
		{
			x1=min(x->x1,x1);
			x2=max(x->x2,x2);
			y1=min(x->y1,y1);
			y2=max(x->y2,y2);
		}
		int Min_Distance(const Point &p)
		{
			int re=0;
			if(p.x<x1) re+=x1-p.x;
			if(p.x>x2) re+=p.x-x2;
			if(p.y<y1) re+=y1-p.y;
			if(p.y>y2) re+=p.y-y2;
			return re;
		}
		int Max_Distance(const Point &p)
		{
			int re=0;
			re+=max(p.x-x1,x2-p.x);
			re+=max(p.y-y1,y2-p.y);
			return re;
		}
	}mempool[M],*C=mempool,*root;
	void Build_Tree(abcd *&x,int l,int r,bool flag)
	{
		if(l>r)
		{
			x=0x0;
			return ;
		}
		int mid=l+r>>1;
		nth_element(points+l,points+mid,points+r+1,flag?Compare_y:Compare_x);
		x=new (C++)abcd(points[mid]);
		Build_Tree(x->ls,l,mid-1,flag^1);
		Build_Tree(x->rs,mid+1,r,flag^1);
		if(x->ls) x->Push_Up(x->ls);
		if(x->rs) x->Push_Up(x->rs);
	}
	void Get_Min(abcd *x,const Point &p,int &ans)
	{
		if(x->p!=p)
			ans=min(ans,Distance(x->p,p));
		int l_dis=x->ls?x->ls->Min_Distance(p):INF;
		int r_dis=x->rs?x->rs->Min_Distance(p):INF;
		if( l_dis < r_dis )
		{
			if( x->ls && l_dis<ans )
				Get_Min(x->ls,p,ans);
			if( x->rs && r_dis<ans )
				Get_Min(x->rs,p,ans);
		}
		else
		{
			if( x->rs && r_dis<ans )
				Get_Min(x->rs,p,ans);
			if( x->ls && l_dis<ans )
				Get_Min(x->ls,p,ans);
		}
	}
	void Get_Max(abcd *x,const Point &p,int &ans)
	{
		ans=max(ans,Distance(x->p,p));
		int l_dis=x->ls?x->ls->Max_Distance(p):-INF;
		int r_dis=x->rs?x->rs->Max_Distance(p):-INF;
		if( l_dis > r_dis )
		{
			if( x->ls && l_dis>ans )
				Get_Max(x->ls,p,ans);
			if( x->rs && r_dis>ans )
				Get_Max(x->rs,p,ans);
		}
		else
		{
			if( x->rs && r_dis>ans )
				Get_Max(x->rs,p,ans);
			if( x->ls && l_dis>ans )
				Get_Max(x->ls,p,ans);
		}
	}
}
int main()
{
	using namespace K_Dimension_Tree;
	int i;
	cin>>n;
	for(i=1;i<=n;i++)
		cin>>points[i];
	Build_Tree(root,1,n,0);
	for(i=1;i<=n;i++)
	{
		int min_dis=INF,max_dis=0;
		Get_Min(root,points[i],min_dis);
		Get_Max(root,points[i],max_dis);
		ans=min(ans,max_dis-min_dis);
	}
	cout<<ans<<endl;
	return 0;
}
时间: 2024-08-18 23:58:37

BZOJ 1941 Sdoi2010 Hide and Seek K-Dimensional-Tree的相关文章

bzoj:1941: [Sdoi2010]Hide and Seek

1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 531  Solved: 295[Submit][Status][Discuss] Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是

BZOJ 1941: [Sdoi2010]Hide and Seek(k-d Tree)

Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 1712  Solved: 932[Submit][Status][Discuss] Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是不够寂寞,于是,他们决定玩寂寞无比的螃蟹版捉迷藏,顾名思义

K-D树:bzoj 1941: [Sdoi2010]Hide and Seek (板子)

1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define ls(x) a[x].l 6 #define rs(x) a[x].r 7 using namespace std; 8 const int N=500066; 9 int abss(int x){return x<0?-x:x;} 10 int maxn(int a,i

bzoj1941 [Sdoi2010]Hide and Seek

Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是不够寂寞,于是,他们决定玩寂寞无比的螃蟹版捉迷藏,顾名思义,就是说他们在玩游戏的时候只能沿水平或垂直方向走.一番寂寞的剪刀石头布后,他们决定iPig去捉giPi.由于他们都很熟悉PKU的地形了,所以giPi只会躲在PKU内n个隐秘地点,显然

【bzoj1941】 Sdoi2010—Hide and Seek

http://www.lydsy.com/JudgeOnline/problem.php?id=1941 (题目链接) 题意 给出n个二维平面上的点,求一点使到最远点的距离-最近点的距离最小. Solution KDtree板子,早就听jump说KDtree都是板子题→_→ 枚举点,求其最远点距离和最近点距离,更新答案.最远邻近域搜索跟最近差不多,就是把估价函数改一下. 细节 码农题注意细节 代码 // bzoj1941 #include<algorithm> #include<iost

【bzoj1941】[Sdoi2010]Hide and Seek KD-tree

题目描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是不够寂寞,于是,他们决定玩寂寞无比的螃蟹版捉迷藏,顾名思义,就是说他们在玩游戏的时候只能沿水平或垂直方向走.一番寂寞的剪刀石头布后,他们决定iPig去捉giPi.由于他们都很熟悉PKU的地形了,所以giPi只会躲在PKU内n个隐秘地点,显然iPig也只会

【kd-tree】bzoj1941 [Sdoi2010]Hide and Seek

枚举每个点,计算离他最近的和最远的点. #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 500001 #define INF 2147483647 #define KD 2//ά¶ÈÊý int qp[KD],disn,disx; int n,root; bool dn; struct Node { int minn[KD],maxx[KD],p[K

【BZOJ】【1941】【SDOI2010】Hide and Seek

KD-Tree 一开始看错题了 其实是:给定n个点,从中找一个点,使得其他所有点到它距离的最大值与最小值之差最小. 利用KD-Tree暴力求出每个点的答案(找离它最近的点以及最远的点(当然只关心距离)) 然后……两个过程分开写…… 注意一下最近的点的距离不能是0(然而我一开始用 if (o==tmp) return INF; 就WA了……)(这里o是当前搜索到的点,tmp是枚举的起始点) 1 /***************************************************

【BZOJ-1941】Hide and Seek KD-Tree

1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 830  Solved: 455[Submit][Status][Discuss] Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是