题目链接: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. Go测试开发(一) 怎么写Go代码

    安装过程略过,网上搜一大把. 介绍 本文会在一个module中开发一个简单的Go package. 同时介绍go tool(也就是go命令行). 以及如何fetch,build和install Go的 ...

  2. 当this碰到return会发生什么

    当this碰到return时 function fn(params) { this.user = 'fzy' return {} } var a = new fn console.log(a.user ...

  3. Oracle中树形查询使用方法

    树形查询一般用于上下级场合,使用的特殊sql语法包括level,prior,start with,connect by等,下面将就实例来说明其用法. 表定义: create table tb_hier ...

  4. 关于Vue-loader的那些事儿

    什么是Vue-loader 一个webpack的加载器,负责将vue组件编译成普通的JavaScript模块. 关于webpack的介绍 这里呢?用到webpack,在项目的编译打包的过程中,将复杂的 ...

  5. SpringBoot搭建环境

    选择文件新建一个项目 选择:Spring Initializr,其他配置不变,点击下一步 这里一般写包名和项目名,这里我就默认,直接点击下一步 这里选择:Web  --> Spring Web ...

  6. 最好用的流程编辑器bpmn-js系列之基本使用

    最好用的流程编辑器bpmn-js系列文章 BPMN(Business Process Modeling Notation)是由业务流程管理倡议组织BPMI(The Business Process M ...

  7. Windows下使用Nginx+Tomact做负载均衡

    前言 今天,王子与大家闲谈一下如何在Windows下使用Nginx+Tomcat做负载均衡的完整步骤,小伙伴们可以试着自己动手实践一下哦. 另外说明一点,本篇文章是纯实操文章,不涉及太多原理的解读,后 ...

  8. EAM在不同行业的应用

    EAM在不同行业的应用 EAM从出现至今,已让很多资产密集型企业受益,甚至在一些行业领域里已经是公认的.不可或缺的管理方案,比如电力行业.轨道交通行业等.但由于不同行业或者企业业务类型不同,导致了资产 ...

  9. Spring系列 之数据源的配置 数据库 数据源 连接池的区别

    Spring系列之数据源的配置 数据源,连接池,数据库三者的区别 连接池:这个应该都学习过,比如c3p0,druid等等,连接池的作用是为了提高程序的效率,因为频繁的去创建,关闭数据库连接,会对性能有 ...

  10. Ubuntu中卸载node和npm并重装

    1.node 和 npm 卸载不干净 #apt-get 卸载 sudo apt-get remove --purge npm sudo apt-get remove --purge nodejs su ...