BZOJ1941Hide and Seek
做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的更多相关文章
- 【SDOI2010题集整合】BZOJ1922~1927&1941&1951&1952&1972&1974&1975
BZOJ1922大陆争霸 思路:带限制的单源最短路 限制每个点的条件有二,路程和最早能进入的时间,那么对两个值一起限制跑最短路,显然想要访问一个点最少满足max(dis,time) 那么每次把相连的点 ...
- 【Android】 修复ijkPlayer进行m3u8 hls流播放时seek进度条拖动不准确的问题
项目中使用的播放器是ijkPlayer,发现播放切片特点的hls流(m3u8格式的视频)拖动seekBar的时候会莫名的跳转或者seek不到准确的位置,发现网友也遇到了同样的问题,ijk的开发者也说明 ...
- 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 ...
- Index Seek和Index Scan的区别
Index Seek是Sql Server执行查询语句时利用建立的索引进行查找,索引是B树结构,Sql Server先查找索引树的根节点,一级一级向下查找,在查找到相应叶子节点后,取出叶子节点的数据. ...
- 【BZOJ-1941】Hide and Seek KD-Tree
1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec Memory Limit: 162 MBSubmit: 830 Solved: 455[Submi ...
- PYTHON seek()tell()语句
print(f.tell()) # 显示当前位置 f.seek(0) #回到某一起点
- stream的seek方法实例
using (FileStream outStream = new FileStream(@"D:\12.txt", FileMode.Open)) { using (FileSt ...
- ai seek
原文地址链接:http://gamedevelopment.tutsplus.com/tutorials/understanding-steering-behaviors-seek--gamedev- ...
- seek指针大文件上传
package mainimport ( // "bufio" "fmt" "github.com/axgle/mahonia&qu ...
随机推荐
- 一、zuul如何路由到上游服务器
所有文章 https://www.cnblogs.com/lay2017/p/11908715.html 正文 zuul在分布式项目中充当着一个网关的角色,而它最主要的功能像nginx一样针对上游服务 ...
- axios配置及使用(发起请求时带上token)
1.安装 利用npm安装 npm install axios --save 2.引入即可使用 import axios from 'axios' 3.目录 4.各个文件设置: (1)env.js ex ...
- input 被checked时和label配合的妙用
input 和label配合的妙用 1:作为文字隐藏与否的开关: 如下代码:对div里面所包含的文字较多,一开始只展示小部分,当用户点击按钮时,进行全部内容的展示(按钮是以向下隐藏箭头的图片) htm ...
- jq的ajax方法
相较与js异步对象的繁琐,jq的ajax对象结构更加清晰 一:ajax对象简述 ajax(Asynchronous JavaScript and XML),异步的xml和js对象,主要用于在不刷新全局 ...
- ArduPilot简介
源码地址:https://github.com/ArduPilot/ardupilot/ 参考:http://ardupilot.org/dev/docs/learning-the-ardupilot ...
- 使用Idea初始化一个spring boot 项目
配置环境 Idea配置jdk8.0 1.打开Idea,点击右上角file,找到Other Settings选项,点击下方的Default Project Structure,如下所示 2.点击下图中所 ...
- 简单使用auth认证实现登录注册
1 添加路由 //注册 Route::get('/register',"RegisterController@index"); Route::post('/register',&q ...
- 异常-No suppression parameter found for notification
1 详细异常 Command Start is not currently available for execution. 关闭 kafka gateway 无法启动 java.lang.NullP ...
- VGridControl 使用技巧
1. 让列的宽度自动填充 如果VGridControl的LayoutStyle属性为BandsView或SingleRecordView,那么把VGridControl的OptionsView.Aut ...
- NodeJS 开发博客(五) 使用express脚手架
1 安装脚手架 npm i express-generator -g 2 使用 express 命令 生成 项目 express-test express express-test 3. npm ...