bzoj-1941 Hide and Seek

原创 2015年11月20日 22:34:27

题意:

给出平面上n个点,求距离每个点最大距离减最小距离(不算自己)的最小值;

n<=500000;


题解:

今天写了两道KDTree然而另一道被常数卡飞。。所以就写这个不需要重构的题解吧;

虽说如此但是这毕竟还是裸题啊。。

KD树在实现的时候需要注意一些问题。。

就是每次到了下一个深度都要换一个不同的比较函数来进行排序建树;

否则似乎就变成和线段树/平衡树一样的东西了,那样剪枝的效果会大大下降;

c++的库函数中有nth_element这个神物来直接找到中间值,并分别将小于和大于的元素放在两边

有了这个似乎真是省去了不少麻烦呢。。

然后就是KD树的强剪枝方法,对于每个结点维护子树内所有点覆盖到的最大的K维几何体;

剪枝条件就是计算这个几何体离查询点的最大/最小距离,然后规划先搜索那个子树,减掉该剪的枝就可以了;

因为这道题没有插入所有还是很兹瓷的!时间复杂度?不知道哦!


代码:


#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 500100
using namespace std;
struct Point
{
	int x[2];
	friend int dis(Point a,Point b)
	{
		return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);
	}
}a[N],low[N],upp[N];
int ch[N][2];
int k,ban,af,ac;
bool cmp(Point a,Point b)
{
	if(a.x[k]!=b.x[k])
	return a.x[k]<b.x[k];
	return a.x[!k]<b.x[!k];
}
void Pushup(int rt)
{
	if(ch[rt][0])
	{
		low[rt].x[0]=min(low[rt].x[0],low[ch[rt][0]].x[0]);
		low[rt].x[1]=min(low[rt].x[1],low[ch[rt][0]].x[1]);
		upp[rt].x[0]=max(upp[rt].x[0],upp[ch[rt][0]].x[0]);
		upp[rt].x[1]=max(upp[rt].x[1],upp[ch[rt][0]].x[1]);
	}
	if(ch[rt][1])
	{
		low[rt].x[0]=min(low[rt].x[0],low[ch[rt][1]].x[0]);
		low[rt].x[1]=min(low[rt].x[1],low[ch[rt][1]].x[1]);
		upp[rt].x[0]=max(upp[rt].x[0],upp[ch[rt][1]].x[0]);
		upp[rt].x[1]=max(upp[rt].x[1],upp[ch[rt][1]].x[1]);
	}
}
int Build(int l,int r,int deep)
{
	if(l>r)	return 0;
	int mid=l+r>>1;
	k=deep&1;
	nth_element(a+l,a+mid,a+r+1,cmp);
	ch[mid][0]=Build(l,mid-1,deep+1);
	ch[mid][1]=Build(mid+1,r,deep+1);
	low[mid]=upp[mid]=a[mid];
	Pushup(mid);
	return mid;
}
int calf(int rt)
{
	return max(abs(low[rt].x[0]-a[ban].x[0]),abs(a[ban].x[0]-upp[rt].x[0]))+
		max(abs(low[rt].x[1]-a[ban].x[1]),abs(a[ban].x[1]-upp[rt].x[1]));
}
int calc(int rt)
{
	return max(low[rt].x[0]-a[ban].x[0],0)+max(a[ban].x[0]-upp[rt].x[0],0)+
		max(low[rt].x[1]-a[ban].x[1],0)+max(a[ban].x[1]-upp[rt].x[1],0);
}
void queryf(int rt)
{
	if(!rt)	return ;
	af=max(af,dis(a[ban],a[rt]));
	int l=calf(ch[rt][0]),r=calf(ch[rt][1]);
	if(l>r)
	{
		if(l>af)	queryf(ch[rt][0]);
		if(r>af)	queryf(ch[rt][1]);
	}
	else
	{
		if(r>af)	queryf(ch[rt][1]);
		if(l>af)	queryf(ch[rt][0]);
	}
}
void queryc(int rt)
{
	if(!rt)	return ;
	if(rt!=ban)
		ac=min(ac,dis(a[ban],a[rt]));
	int l=calc(ch[rt][0]),r=calc(ch[rt][1]);
	if(l<r)
	{
		if(l<ac)	queryc(ch[rt][0]);
		if(r<ac)	queryc(ch[rt][1]);
	}
	else
	{
		if(r<ac)	queryc(ch[rt][1]);
		if(l<ac)	queryc(ch[rt][0]);
	}
}
int main()
{
	int n,m,i,j,k,x,y,rt,ans;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		scanf("%d%d",a[i].x,a[i].x+1);
	rt=Build(1,n,0);
	ans=0x3f3f3f3f;
	for(i=1;i<=n;i++)
	{
		ban=i;
		af=0;
		ac=0x3f3f3f3f;
		queryf(rt);
		queryc(rt);
		ans=min(ans,af-ac);
	}
	printf("%d\n",ans);
	return 0;
}



[BZOJ1941][Sdoi2010]Hide and Seek(kd-tree)

题目描述传送门题解sdoi竟然会考kd-tree裸题= =惊恐脸 询问每一个点的最近点和最远点然后更新答案就行了代码#include #include #include #include #incl...
  • Clove_unique
  • Clove_unique
  • 2017年02月10日 16:41
  • 592

bzoj 1941: [Sdoi2010]Hide and Seek (KD-tree)

1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MB Submit: 1001  Solved: 524 [Su...
  • clover_hxy
  • clover_hxy
  • 2016年12月27日 09:17
  • 169

【bzoj1941】[Sdoi2010]Hide and Seek

Description小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏—捉...
  • w_yqts
  • w_yqts
  • 2017年05月17日 19:31
  • 116

[BZOJ1941][Sdoi2010]Hide and Seek

Kdtree第一题.讲一下Kdtree: Kdtree的用途是对高维向量(点)进行各种索引.
  • Zvezda_
  • Zvezda_
  • 2016年02月23日 22:08
  • 631

1941: [Sdoi2010]Hide and Seek|K-D Tree

算是一道裸的kdtree的题了,为什么这么慢QAQ 一遍提交进入最后一页也是种艺术#include #include #include #include #include #include #inc...
  • ws_yzy
  • ws_yzy
  • 2016年03月11日 13:50
  • 432

E - GirlCat

As a cute girl, Kotori likes playing ``Hide and Seek'' with cats particularly.  Under the influence...
  • Dreamlandz
  • Dreamlandz
  • 2017年04月19日 21:20
  • 225

hdu 5706 GirlCat【暴力DFS】

GirlCat Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...
  • mengxiang000000
  • mengxiang000000
  • 2016年05月30日 18:01
  • 604

1941: [Sdoi2010]Hide and Seek|动态加点线段树

传统的K-Dtree姿势http://blog.csdn.net/ws_yzy/article/details/50855522 对计算曼哈顿距离分四种情况讨论,枚举每一个点,维护它的左下,左上,右...
  • ws_yzy
  • ws_yzy
  • 2016年03月11日 15:42
  • 710

hdu 5706 GirlCat(深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5706 ——报考杭州电子科技大学! GirlCat T...
  • qiqi_skystar
  • qiqi_skystar
  • 2016年07月03日 13:44
  • 1720

Hdoj 5706 GirlCat

Problem Description As a cute girl, Kotori likes playing Hide and Seek'' with cats particularly. U...
  • Sentiment_logos
  • Sentiment_logos
  • 2017年12月27日 11:29
  • 86
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj-1941 Hide and Seek
举报原因:
原因补充:

(最多只允许输入30个字)