题目链接: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. Labview学习之路(十三)数组函数

    本文章介绍一下函数选版中的数组函数,一眼看懂没什么特殊地方的就不说了 (一)数组大小 返回I32类型的数或者数组. 什么是I32类型?就是32位有符号整型, 有符号什么意思?就是在32位数据中最高做符 ...

  2. 2d 骨胳动画

    cocos2d下,优秀骨骼spine的换装思路 https://www.jianshu.com/p/a0019c6cf7ba

  3. ORA-01033错误解决方案-九五小庞

    Microsoft Windows [版本 6.3.9600](c) 2013 Microsoft Corporation.保留所有权利. C:\Users\Administrator>sqlp ...

  4. [LeetCode题解]79. 单词搜索

    题目描述 题目:79. 单词搜索 解题思路 遍历 首先找重复性,题目说给定单词是否存在于二维数组中,可以简化为从 (x, y) 走 n 步(n 表示单词长度),查看给定单词是否存在.然后再遍历二维数组 ...

  5. XmlAnalyzer1.00 源码

    此工程用途:将xml同级属性/子节点按字母序排列重新输出. 源码下载: https://files.cnblogs.com/files/heyang78/XmlAnalyzer-20200526-1. ...

  6. Prmise.all的简单实现

    注意点 入参一般是个由Promise实例组成的数组,但是也可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例.若参数如果不是 Promise 实例,就会先调用 ...

  7. core的 Linq基本使用,简单模拟数据库多表的左右内连接的测试

    1:先看效果: 2:部分代码截图 3:全部代码 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 n ...

  8. 不光是查找值!"二分搜索"

    从有序数组中查找某个值 问题描述:给定长度为n的单调不下降数列a0,…,an-1和一个数k,求满足ai≥k条件的最小的i.不存在则输出n. 限制条件:1≤n≤1060≤a0≤a1≤…≤an-1< ...

  9. Django循环创造div后,对各个div操作后触发事件,传递数据(Django九)

    前面我用for循环创建了div,每个div中有各自的数据以及同样的布局 效果图如下:部分代码如下: 现在,我希望在点击每个div里的发表按钮时,能在js里获取{{problem.pro_id}}以及{ ...

  10. CentOS中rpm和yum到底有什么区别?

    2020/5/19 (   Linux 软件安装的学习链接:http://c.biancheng.net/view/814.html    ) 一.rpm 是什么? rpm 全称 Red-Hat Pa ...