做KD_tree的入门题。

问题就是求出任意一个点距其他点的最大曼哈顿距离和最小曼哈顿距离差,然后对其取min即可。

这个东西就是KD_tree可以轻松解决的了。

下面总结一下做KD_tree(不带修)的心得。

KD_tree本质上是一颗搜索树,实际上将所有可能的决策集合不重不漏的划分了出来,而我们要做的就是剪枝。

其实建KD_tree的过程就是将一个平面划分成若干小块,即子问题,来方便我们查找,一般的KD_tree需要以下内容:

首先左右儿子是必备的。然后注意一个非常重要的事情,我们划分的时候是有基准的,我们建立KD_tree的时候,每一个节点都包含着一个真实的点,我称之为基准点(BP),我们递归进行的时候就是利用BP来更新ans。接着就是剪枝用的组件,在本题中,我们维护矩形的4个边界,只有我们用估价函数算出的值比较优秀的时候我们才向下进行,因为估价函数考虑的是最优情况,如果这种可能性很小的最优情况都不满足,那么别的条件就更没用了,我们不需要进入这颗子树。

接着一个New函数是KD_tree建立的基础,我们将上述组件全部赋好初值,(因为野针确实可pia)。

pushup函数就如同线段树一般,我们维护的信息大多可以“区间”合并。

cal估价函数是KD_tree的灵魂,否则KD_tree有时就是大暴力(其实加了剪枝也像暴力)。

接着开始快乐建树。

r>l就return,开点,换now,nth_element找中位,维护自身信息,递归左右儿子,pushup,建完收工。

然后进行快乐查询。

空指针,return,用当前节点的BP尝试更新答案,求出左右儿子估价值,先跑更优的,因为跑完它以后那个次优的可能就不用跑了。

完成。

#include<bits/stdc++.h>
#define null NULL
using namespace std;
const int N=;
const int inf=0x7fffffff;
inline int read(){
int sum(),f();char x=getchar();
while(x<''||x>''){
if(x=='-') f=-;
x=getchar();
}while(x>=''&&x<=''){
sum=sum*+x-'';
x=getchar();
}return sum*f;
}
inline int abs_(int x){
return x<?-x:x;
}
inline int min_(int x,int y){
return x<y?x:y;
}
inline int max_(int x,int y){
return x>y?x:y;
}
int now,n,ans=inf,tot,Maxans,Minans;
struct node{
int x[];//x,y坐标
}poi[N];
bool comp(node a,node b){
return a.x[now]<b.x[now];
}
inline int Mhtdis(node a,node b){
return abs_(a.x[]-b.x[])+abs_(a.x[]-b.x[]);
}
struct Kd_tree{
Kd_tree *ch[];
node BP;
int minv[],maxv[];
inline void New(node a){
BP=a;
minv[]=maxv[]=a.x[];
minv[]=maxv[]=a.x[];
ch[]=ch[]=null;
}
inline void pushup(){
if(ch[]){
minv[]=min_(minv[],ch[]->minv[]);
maxv[]=max_(maxv[],ch[]->maxv[]);
minv[]=min_(minv[],ch[]->minv[]);
maxv[]=max_(maxv[],ch[]->maxv[]);
}
if(ch[]){
minv[]=min_(minv[],ch[]->minv[]);
maxv[]=max_(maxv[],ch[]->maxv[]);
minv[]=min_(minv[],ch[]->minv[]);
maxv[]=max_(maxv[],ch[]->maxv[]);
}
}
inline int cal_min(node a){
return max_(minv[]-a.x[],)+max_(a.x[]-maxv[],)
+max_(minv[]-a.x[],)+max_(a.x[]-maxv[],);
}
inline int cal_max(node a){
return max_(abs_(a.x[]-minv[]),abs_(a.x[]-maxv[]))
+max_(abs_(a.x[]-minv[]),abs_(a.x[]-maxv[]));
}
}*root,pool[N];
void build(Kd_tree *&p,int l,int r,int d){
if(l>r) return ;
p=pool+(tot++); now=d;
int mid=l+r>>;
nth_element(poi+l,poi+mid,poi+r,comp);
p->New(poi[mid]);
build(p->ch[],l,mid-,d^);
build(p->ch[],mid+,r,d^);
p->pushup();
}
void query_max(Kd_tree *p,node rec){
if(p==null) return ;
Maxans=max_(Mhtdis(p->BP,rec),Maxans);
int dis[]={p->ch[]==null?:p->ch[]->cal_max(rec),
p->ch[]==null?:p->ch[]->cal_max(rec)};
int first=dis[]>dis[]?:;
if(dis[first]>Maxans) query_max(p->ch[first],rec);
if(dis[first^]>Maxans) query_max(p->ch[first^],rec);
}
void query_min(Kd_tree *p,node rec){
if(p==null) return ;
if(Mhtdis(p->BP,rec))
Minans=min_(Mhtdis(p->BP,rec),Minans);
int dis[]={p->ch[]==null?inf:p->ch[]->cal_min(rec),
p->ch[]==null?inf:p->ch[]->cal_min(rec)};
int first=dis[]<dis[]?:;
if(dis[first]<Minans) query_min(p->ch[first],rec);
if(dis[first^]<Minans) query_min(p->ch[first^],rec);
}
inline int query_max(node rec){
Maxans=;
query_max(root,rec);
return Maxans;
}
inline int query_min(node rec){
Minans=inf;
query_min(root,rec);
return Minans;
}
int main(){
n=read();
for(int i=;i<=n;++i){
poi[i].x[]=read();
poi[i].x[]=read();
}
build(root,,n,);
for(int i=;i<=n;++i)
ans=min_(ans,query_max(poi[i])-query_min(poi[i]));
printf("%d",ans);
return ;
}

(论循环展开的优越性)

BZOJ1941Hide and Seek的更多相关文章

  1. 【SDOI2010题集整合】BZOJ1922~1927&1941&1951&1952&1972&1974&1975

    BZOJ1922大陆争霸 思路:带限制的单源最短路 限制每个点的条件有二,路程和最早能进入的时间,那么对两个值一起限制跑最短路,显然想要访问一个点最少满足max(dis,time) 那么每次把相连的点 ...

  2. 【Android】 修复ijkPlayer进行m3u8 hls流播放时seek进度条拖动不准确的问题

    项目中使用的播放器是ijkPlayer,发现播放切片特点的hls流(m3u8格式的视频)拖动seekBar的时候会莫名的跳转或者seek不到准确的位置,发现网友也遇到了同样的问题,ijk的开发者也说明 ...

  3. POJ 2752 Seek the Name, Seek the Fame [kmp]

    Seek the Name, Seek the Fame Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17898   Ac ...

  4. Index Seek和Index Scan的区别

    Index Seek是Sql Server执行查询语句时利用建立的索引进行查找,索引是B树结构,Sql Server先查找索引树的根节点,一级一级向下查找,在查找到相应叶子节点后,取出叶子节点的数据. ...

  5. 【BZOJ-1941】Hide and Seek KD-Tree

    1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 830  Solved: 455[Submi ...

  6. PYTHON seek()tell()语句

    print(f.tell()) # 显示当前位置 f.seek(0) #回到某一起点

  7. stream的seek方法实例

    using (FileStream outStream = new FileStream(@"D:\12.txt", FileMode.Open)) { using (FileSt ...

  8. ai seek

    原文地址链接:http://gamedevelopment.tutsplus.com/tutorials/understanding-steering-behaviors-seek--gamedev- ...

  9. seek指针大文件上传

    package mainimport (    // "bufio"    "fmt"    "github.com/axgle/mahonia&qu ...

随机推荐

  1. cmake用法及常用命令总结(全)

    CMakeLists.txt 的语法比较简单,由命令.注释和空格组成,其中命令是不区分大小写的.指令是大小写无关的,参数和变量是大小写相关的.但推荐全部使用大写指令.符号 # 后面的内容被认为是注释. ...

  2. 原生js实现ajax封装

    一.什么是ajax? 定义:Ajax(Asynchronous Java and XML的缩写)是一种异步请求数据的web开发技术,在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并 ...

  3. shiro系列五、shiro密码MD5加密

    Shiro-密码的MD5加密   1.密码的加密 在数据表中存的密码不应该是123456,而应该是123456加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密 ...

  4. 四:MySQL系列之Python交互(四)

    该篇主要介绍MySQL数据库的分表.以及与Python的交互的基本操作等. 一.拆分表操作 1.1  准备工作 创建数据库 --> 使用数据库 --> 创建数据表 --- 添加记录 -- ...

  5. [dev][ipsec][esp] ipsec链路中断的感知问题

    ipsec如何感知到链路中断了?以下内容讲的是在没有配置DPD,且没有rekey的场 景下. 1. ESP认为,以下两个场景交由应用层来感知,应用层会发现ipsec的连接坏掉了. a,ESP承载的连接 ...

  6. 部署Nginx网站服务实现访问状态统计以及访问控制功能

    原文:https://blog.51cto.com/11134648/2130987 Nginx专为性能优化而开发,最知名的优点是它的稳定性和低系统资源消耗,以及对HTTP并发连接的高处理能力,单个物 ...

  7. MyEclipse修改运行内存

    修改  myeclipse.ini -vmargs -Xmx1768m -XX:MaxPermSize=1320m -XX:ReservedCodeCacheSize=64m -Dosgi.nls.w ...

  8. linux网络编程之socket编程(十)

    今天继续socket编程的学习,最近晚上睡觉都没有发热,没有暖气的日子还是种煎熬,快乐的十一也已经走来,幸福有暖气的日子也快啦,好了,回到正题~ ①close终止了数据传送的两个方向. ②shutdo ...

  9. Ubuntu增加swap交换空间的步骤

    1.首先用命令free查看系统内 Swap 分区大小. free -m total used free shared buffers cached Mem: 2012 1960 51 0 748 95 ...

  10. 云计算(2)-Cloud是什么

    Cloud是什么 compute cycles应建立在data center的附近而不是data center围绕着compute cycles Two kinds of clouds Example ...