题目链接:https://www.luogu.com.cn/problem/P2479

题目大意:求平面\(n\)个点中,到其它\(n-1\)个点的曼哈顿距离最大和最小距离之差最小的点,求出这个这个距离差。

用\(K-D-Tree\)维护区间,剪枝搜索。

值得一提的是,对于\(maxdis\)的查询还是比较显然的,找到它到当前点所维护区间的端点的距离的最大值即可。对于最小距离……还是(对我来说)有点坑的。

首先,判断最小距离的时候,当这个点在当前询问区间的话,它的距离显示为0,就炸了qwq,所以,求完这个距离,我们更新答案的时候应该判断是否是真的这个距离,即为零不更新。

那么其它的都和\(k\)远点对差不多,没有重构,没有替罪羊

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int MAXN=5e5+10;
#define inf 2147483647
struct pt{
int x[2];
}p[MAXN];
int rt,D,tot,n,ans,ans1,ans2;
int ls[MAXN],rs[MAXN];
struct node{
int mi[2],mx[2],siz;
pt c;
}tr[MAXN];
inline void pushup(int x){
int l=ls[x],r=rs[x];
tr[x].siz=tr[l].siz+tr[r].siz+1;
for(int i=0;i<=1;++i){
tr[x].mi[i]=tr[x].mx[i]=tr[x].c.x[i];
if(l)tr[x].mi[i]=min(tr[x].mi[i],tr[l].mi[i]),tr[x].mx[i]=max(tr[x].mx[i],tr[l].mx[i]);
if(r)tr[x].mi[i]=min(tr[x].mi[i],tr[r].mi[i]),tr[x].mx[i]=max(tr[x].mx[i],tr[r].mx[i]);
}
}
int operator<(pt a,pt b){return a.x[D]<b.x[D];}
int build(int l,int r,int d){
if(l>r)return 0;
int x=++tot,mid=l+r>>1;
D=d;nth_element(p+l,p+mid,p+r+1);
tr[x].c=p[mid];ls[x]=build(l,mid-1,d^1);
rs[x]=build(mid+1,r,d^1);pushup(x);return x;
}
inline int abs(int x){return x<0?-x:x;}
inline int Get(pt x,pt y){return abs(x.x[0]-y.x[0])+abs(x.x[1]-y.x[1]);}
int Getdis(int x,pt a){
int res=0;
for(int i=0;i<=1;++i){
res+=max(0,a.x[i]-tr[x].mx[i])+max(0,tr[x].mi[i]-a.x[i]);
}
return res;//min
}
int getdis(int x,pt a){
int res=0;
for(int i=0;i<=1;++i)res+=max(abs(tr[x].mi[i]-a.x[i]),abs(tr[x].mx[i]-a.x[i]));
return res;//max
}
void querymax(int x,pt y){
ans2=max(ans2,Get(tr[x].c,y));
int l=ls[x],r=rs[x],dl,dr;
dl=l?getdis(l,y):-inf;
dr=r?getdis(r,y):-inf;
if(dl>dr){
if(dl>ans2)querymax(l,y);
if(dr>ans2)querymax(r,y);
}
else{
if(dr>ans2)querymax(r,y);
if(dl>ans2)querymax(l,y);
}
}
void querymin(int x,pt y){
int tmp=Get(tr[x].c,y);
if(tmp)ans1=min(ans1,tmp);
int l=ls[x],r=rs[x],dl,dr;
dl=l?Getdis(l,y):inf;
dr=r?Getdis(r,y):inf;
if(dl<dr){
if(dl<ans1)querymin(l,y);
if(dr<ans1)querymin(r,y);
}
else{
if(dr<ans1)querymin(r,y);
if(dl<ans1)querymin(l,y);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d%d",&p[i].x[0],&p[i].x[1]);
rt=build(1,n,0);ans=inf;
for(int i=1;i<=n;++i){
ans1=inf,ans2=-inf;
querymax(rt,p[i]);
querymin(rt,p[i]);
ans=min(ans,ans2-ans1);
//cout<<"Casepoint"<<i<<":"<<ans<<" "<<ans2<<" "<<ans1<<endl;
}
printf("%d\n",ans);
return 0;
}

【题解】[SDOI2010]捉迷藏的更多相关文章

  1. [SDOI2010]捉迷藏 K-Dtree

    [SDOI2010]捉迷藏 链接 luogu 思路 k-dtree模板题 代码 #include <bits/stdc++.h> #define ls (t[u].ch[0]) #defi ...

  2. [题解] [SDOI2010] 古代猪文

    题面 题解 题目所求即为 \[ G ^ {\sum_{d | n}C_{n}^{d}} \bmod {999911659} \] 考虑到有这样一个式子 \[ a ^ b \equiv a ^ {b \ ...

  3. [SDOI2010]捉迷藏

    嘟嘟嘟 k-d tree板儿题. 建完树后对每一个点求一遍最小和最大曼哈顿距离,是曼哈顿,不是欧几里得. #include<cstdio> #include<iostream> ...

  4. luoguP2479 [SDOI2010]捉迷藏

    https://www.luogu.org/problemnew/show/P2479 据说可以用线段树做但是我不会,只能写一个 KD-Tree 了 对于每个点求出距离它最远的点和最近的点的距离,然后 ...

  5. P2479 [SDOI2010]捉迷藏

    传送门 KDtree是个吼东西啊-- 枚举每一个点,然后求出离他距离最远和最近的点的距离,更新答案 然而为什么感觉KDtree只是因为剪枝才能跑得动呢-- //minamoto #include< ...

  6. 题解 [SDOI2010] 大陆争霸

    题面 解析 这题似乎不是那么难啊 首先,显而易见, 如果要摧毁一个城市,必须要满足两个条件: 机器人摧毁了保护它的城市. 机器人到达了这个城市. 而这两个条件可以同时进行(毕竟有无数机器人) 那么显然 ...

  7. 模板—K-D-tree(P2479 [SDOI2010]捉迷藏)

    #include<algorithm> #include<iostream> #include<cstdio> #include<cmath> #def ...

  8. 题解 SDOI2010 【栗栗的书架】

    \[ Preface \] 看到这题洛谷标签有 主席树 ,还以为是什么二维主席树的玄学做法(雾 \[ Description \] 给出一个 \(R×C\) 的矩阵. 一共 \(m\) 次询问,每次询 ...

  9. 题解 [SDOI2010]所驼门王的宝藏

    传送门 保分题再度爆零,自闭ing×2 tarjan没写vis数组,点权算的也有点问题 这题情况3的连边有点麻烦,考场上想了暴力想了二分就是没想到可以直接拿map水过去 不过map果然贼慢,所以这也是 ...

随机推荐

  1. String painter (区间dp)

    There are two strings A and B with equal length. Both strings are made up of lower case letters. Now ...

  2. deepin20 安装英伟达闭源驱动

    第一步.安装深度的"显卡驱动器" 在deepin v20 中默认没有显卡驱动管理器,需要命令行安装,命令如下(刚开始一直出错,当我第一次打开应用商店,就可以安装了,好神奇): su ...

  3. C#发送邮件三种方法,Localhost,SMTP,SSL-SMTP

    C#发送邮件三种方法,Localhost,SMTP,SSL-SMTP 通过.Net FrameWork 2.0下提供的“System.Net.Mail”可以轻松的实现,本文列举了3种途径来发送: 1. ...

  4. Ajax跨域解决方案大全

    题纲 关于跨域,有N种类型,本文只专注于ajax请求跨域(,ajax跨域只是属于浏览器"同源策略"中的一部分,其它的还有Cookie跨域iframe跨域,LocalStorage跨 ...

  5. python基础:用yagmail模块发邮件

    一.yagmail模块安装 网上下载的yagmail模块安装以后,在使用过程中,如果附件有中文,会显示乱码. pip install yagmail-0.10.212-py2.py3-none-any ...

  6. 学习 | css3实现进度条加载

    进度条加载是页面加载时的一种交互效果,这样做的目的是提高用户体验. 进度条的的实现分为3大部分:1.页面布局,2.进度条动效,3.何时进度条增加. 文件目录 加载文件顺序 <link rel=& ...

  7. Python爬虫实战练习:爬取美团旅游景点评论数据

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 今年的国庆节还有半个月就要来了,相信很多的小伙伴还是非常期待这个小长假的.国庆节是一年中的小 ...

  8. Linux实战(13):Centos8安装FFmpeg

    此文章所做的操作参考漏网的鱼:参考链接 步骤1:安装RPMfusion Yum存储库 RHEL或兼容发行版(如CentOS)上启用EPEL. dnf -y install https://downlo ...

  9. firewalld 防火墙

    firewalld防火墙   firewalld简述 firewalld:防火墙,其实就是一个隔离工具:工作于主机或者网络的边缘对于进出本主机或者网络的报文根据事先定义好的网络规则做匹配检测,对于能够 ...

  10. MATLAB 与 Excel 接口

    MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式:一种是通过 MATLAB 提供的 Excel 生成器,生成220 MATLAB 实用教程DLL 组件和 VBA 代码,实 ...