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 ...
随机推荐
- 【转】使用Scanner输入字符串时next()和nextLine()区别
在实现字符窗口的输入时,很多人更喜欢选择使用扫描器Scanner,它操作起来比较简单.在编程的过程中,我发现用Scanner实现字符串的输入有两种方法,一种是next(),一种nextLine(),但 ...
- vue使用技巧:Promise + async + await 解决组件间串行编程问题
业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...
- https、加密安全
1.Https HTTPS在传输的过程中会涉及到三个密钥: 服务器端的公钥和私钥,用来进行非对称加密 客户端生成的随机密钥,用来进行对称加密 一个HTTPS请求实际上包含了两次HTTP传输,可以细分为 ...
- 使用js解决response.sendRedirect("...")重定向URL之后出现跨域问题
背景: 本系统与门户系统单点登录时候,需要重定向到门户系统的登录页面,可是如果长时间没有操作的话,session会话失效,就需要跳转到登录页面. 所以在使用 response.sendRedirect ...
- Pandas-数据处理-基础部分
有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/11014882.html jupyter 代码 ...
- iPhone电话与短信相关代码小结
关于iPhone上电话与短信相关功能,做一个简单总结: 使用公开SDK能实现的功能: (1)获取和操作通讯录.使用函数 ABAddressBookRequestAccessWithCompletion ...
- TLS1.3 认证和秘钥建立握手环节的分析
1.ClientHello 中的参数 ClientHello---{ Random_C .extension } 在 extension中的扩展中包含 ( supported_version ...
- 轻院校赛-zzuli 2266: number【用每位的二进制的幂的和来进行hash(映射)处理】
zzuli 2266: number 大致题意: 给定n,问有多少数对<x, y>满足: x, y∈[1, n], x < y x, y中出现的[0, 9] ...
- Pycharm----【Mac】设置默认模板
使用场景:新建的文件中,有某些字段或者代码段是每次都需要写入的,因此为了编写的方便,我们会创建对应的模板,每次新建选择模板即可. 操作步骤如下: pycharm--->preference--- ...
- 国内可用的python源
国内可用的python源 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/ 阿里云:http://mirrors.aliyun.com/pypi/simpl ...