【BZOJ1941】【SDOI2010】Hide and Seek、KDTree【数组版】 模板、

直接贴代码。

推荐一篇KDT讲解、http://blog.csdn.net/wyfcyx_forever/article/details/40182345

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 501000
#define inf 0x3f3f3f3f
#define d(x,y) (((x)>(y))?((x)-(y)):((y)-(x)))
using namespace std;

int n,ans=inf;

int judge;
struct Point
{
	int x,y;
	Point(int _x=0,int _y=0):x(_x),y(_y){}
	bool operator < (const Point &a)const
	{return judge?y<a.y:x<a.x;}
}P[N];
inline int dis(Point &a,Point &b){return d(a.x,b.x)+d(a.y,b.y);}
struct KDT
{
	int son[N][2],cnt;
	int x[N][2],y[N][2];
	void init(int a,Point &p)
	{
		x[a][0]=x[a][1]=p.x;
		y[a][0]=y[a][1]=p.y;
	}
	void update(int f)
	{
		int s;
		if(son[f][0])
		{
			s=son[f][0];
			x[f][0]=min(x[f][0],x[s][0]);
			y[f][0]=min(y[f][0],y[s][0]);
			x[f][1]=max(x[f][1],x[s][1]);
			y[f][1]=max(y[f][1],y[s][1]);
		}
		if(son[f][1])
		{
			s=son[f][1];
			x[f][0]=min(x[f][0],x[s][0]);
			y[f][0]=min(y[f][0],y[s][0]);
			x[f][1]=max(x[f][1],x[s][1]);
			y[f][1]=max(y[f][1],y[s][1]);
		}
	}
	int maxdis(int a,Point &p)
	{
		int ret=0;
		ret+=max(d(x[a][0],p.x),d(x[a][1],p.x));
		ret+=max(d(y[a][0],p.y),d(y[a][1],p.y));
		return ret;
	}
	int mindis(int a,Point &p)
	{
		int ret=0;
		if(p.x<x[a][0])ret+=x[a][0]-p.x;
		else if(x[a][1]<p.x)ret+=p.x-x[a][1];
		if(p.y<y[a][0])ret+=y[a][0]-p.y;
		else if(y[a][1]<p.y)ret+=p.y-y[a][1];
		return ret;
	}
	int newnode(Point &p)
	{
		init(++cnt,p);
		return cnt;
	}
	int build(int l,int r,int jd=0)
	{
		int mid=l+r>>1,t=0;
		judge=jd;
		nth_element(P+l,P+mid,P+r+1);
		if(l<mid)t=build(l,mid-1,!jd);
		int q=newnode(P[mid]);son[q][0]=t;
		if(mid<r)son[q][1]=build(mid+1,r,!jd);
		update(q);
		return q;
	}
	int Maxdis,Mindis;
	void querymin(int f,Point &p)
	{
		int Dis[3];
		Dis[2]=dis(P[f],p);
		if(Dis[2])Mindis=min(Mindis,Dis[2]);

		Dis[0]=Dis[1]=inf;
		if(son[f][0])Dis[0]=mindis(son[f][0],p);
		if(son[f][1])Dis[1]=mindis(son[f][1],p);
		int t=Dis[0]>Dis[1];
		if(son[f][t]&&Dis[t]<Mindis)querymin(son[f][t],p);
		t^=1;if(son[f][t]&&Dis[t]<Mindis)querymin(son[f][t],p);
	}
	void querymax(int f,Point &p)
	{
		int Dis[3];
		Dis[2]=dis(P[f],p);
		if(Dis[2])Maxdis=max(Maxdis,Dis[2]);

		Dis[0]=Dis[1]=0;
		if(son[f][0])Dis[0]=maxdis(son[f][0],p);
		if(son[f][1])Dis[1]=maxdis(son[f][1],p);
		for(int i=2,t=Dis[0]<Dis[1];i--;t^=1)
			if(son[f][t]&&Dis[t]>Maxdis)querymax(son[f][t],p);
	}
	int query(int root,int q)
	{
		Mindis=inf,Maxdis=0;
		querymax(root,P[q]),querymin(root,P[q]);
//		printf("(%d,%d) : %d %d\n",P[q].x,P[q].y,Mindis,Maxdis);
		return Maxdis-Mindis;
	}
}kdt;
int main()
{
//	freopen("test.in","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d%d",&P[i].x,&P[i].y);
	int root=kdt.build(1,n);
	for(int i=1;i<=n;i++)ans=min(ans,kdt.query(root,i));
	printf("%d\n",ans);
	return 0;
}
时间: 2024-12-16 12:59:36

【BZOJ1941】【SDOI2010】Hide and Seek、KDTree【数组版】 模板、的相关文章

【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(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是

【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

bzoj1941 [Sdoi2010]Hide and Seek

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

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(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是

「Splay」指针版与数组版模板

splay总是多打打就熟了,先把板子贴在这里方便查看 Splay的思想还是很简单的,反正就是把每次查询到的都splay到根,维护动态平衡 插入的时候就找到位置,splay到根 删除是最麻烦的,先查找到它并splay到根.然后找到前驱splay到根的左子节点作为根,废掉原先的根节点,然后把右子节点接到前驱的右子树上. 排名只要splay到根输出左子树+1就好了 kth也不难,从根开始,如果不够就往左走,要么是自己,再不行就往右边走.不要忘了k要减掉左子树和cnt 前驱后继只要先插入查一下再删掉就好

【bzoj1941】 Sdoi2010—Hide and Seek

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

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

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