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 ...
随机推荐
- Go net/http 发送常见的 http 请求
使用 golang 中的 net/http 包来发送和接收 http 请求 开启 web server 先实现一个简单的 http server,用来接收请求 package main import ...
- jQuery 基础知识
一.序言 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后的又一个优秀的JavaScript代码库(JavaScript框架).jQuery设计的宗旨是"W ...
- 什么是Familywise Error Rate
1.什么是Familywise Error Rate(FWE or FWER) 定义:在一系列假设检验中,至少得出一次错误结论的概率. 换句话说,是造成至少一次Type I Error的概率.术语FW ...
- 如何给SAP云平台的账号分配Leonardo机器学习服务的实例
首先点击Entitlements下面的Service Assignments,查看是否有SAP Leonardo Machine Learning Foundation这个服务: 点击SubAccou ...
- 【Linux】修改CentOS7启动方式
## 查看当前系统的默认启动方式: systemctl get-default ## 查看如下文件 cat /etc/inittab 可以看到 此文件中提示了如何进行修改默认的启动方式 ## 命令行启 ...
- Spark foreachpartiton和mappartition的异同
相同 都是对分区进行操作 不同 1.foreachpartition是Action操作,mappartition是Transformation操作 2.foreachpartition无返回值,map ...
- Python Django开发遇到的坑(版本不匹配)
这个问题 进入django 后台, 添加,修改都不可以,只有删除可以,那么百分之百是这个问题 对照一下,是你的django 版本低了还是 python版本高了,对照的话就没问题了 这个坑,弄了两天啊! ...
- iptables详解(6):iptables扩展模块之 state 扩展
为了防止恶意攻击主动连接到你的主机 我们需要通过iptables的扩展模块判断报文是为了回应我们之前发出的报文还是主动向我们发送的报文 state模块可以让iptables实现 连接追踪机制 NEW表 ...
- ES6 解构赋值详解
解构赋值是对赋值运算符的扩展,可以将属性/值从对象/数组中取出,赋值给其他变量. 一.数组的解构赋值 1.基本用法 只要等号两边的模式相同,左边的变量就会被赋予对应的值. let [a, [[b], ...
- 3星|路骋《用得上的商学院》:100个MBA知识点的简单介绍
作者在序言中说,放弃了上亿的股票期权去念了两年全脱产的清华-MIT Global MBA.念完后认为课程不错,考虑到这种课本科毕业不能直接念,工作几年后又很难脱产来念,因此办了一个音频课程来讲这个MB ...