luoguP2479 [SDOI2010]捉迷藏
https://www.luogu.org/problemnew/show/P2479
据说可以用线段树做但是我不会,只能写一个 KD-Tree 了
对于每个点求出距离它最远的点和最近的点的距离,然后取 min 即可
因为这个东西是可以剪枝的,所以跑的挺快的
#include <bits/stdc++.h>
#define For(i, a, b) for(int i = a; i <= b; i++)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
template <typename _T>
inline void read(_T &f) {
f = 0; _T fu = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();}
while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}
f *= fu;
}
const int N = 1e5 + 5;
int WD, siz, n, root;
struct po {
int a[2];
bool operator < (const po A) const {return a[WD] < A.a[WD];}
}t[N];
struct Node {
int mn[2], mx[2], lc, rc;
po tp;
}p[N];
void update(int u) {
int l = p[u].lc, r = p[u].rc;
for(register int i = 0; i <= 1; i++) {
p[u].mn[i] = p[u].mx[i] = p[u].tp.a[i];
if(l) p[u].mn[i] = min(p[u].mn[i], p[l].mn[i]), p[u].mx[i] = max(p[u].mx[i], p[l].mx[i]);
if(r) p[u].mn[i] = min(p[u].mn[i], p[r].mn[i]), p[u].mx[i] = max(p[u].mx[i], p[r].mx[i]);
}
}
int build(int l, int r, int wd) {
if(l > r) return 0;
int u = ++siz, mid = (l + r) >> 1;
WD = wd; nth_element(t + l, t + mid, t + r + 1);
p[u].tp = t[mid]; p[u].lc = build(l, mid - 1, wd ^ 1); p[u].rc = build(mid + 1, r, wd ^ 1);
update(u); return u;
}
// 最小距离
int calc1(int u, po tp) {
int ans = 0;
for(register int i = 0; i <= 1; i++) ans += max(0, p[u].mn[i] - tp.a[i]) + max(0, tp.a[i] - p[u].mx[i]);
return ans;
}
int calc2(int u, po tp) {
int ans = 0;
for(register int i = 0; i <= 1; i++) ans += max(abs(tp.a[i] - p[u].mn[i]), abs(tp.a[i] - p[u].mx[i]));
return ans;
}
int dis(po a, po b) {
int ans = 0;
for(register int i = 0; i <= 1; i++) ans += abs(a.a[i] - b.a[i]);
return ans;
}
const int INF = 0x7f7f7f7f;
int ans1, ans2;
void query1(int u, po tp) {
if(!u) return;
int now = dis(p[u].tp, tp);
if(ans1 > now && now) ans1 = now;
int l = INF, r = INF;
if(p[u].lc) l = calc1(p[u].lc, tp);
if(p[u].rc) r = calc1(p[u].rc, tp);
if(l < r) {
if(l < ans1) query1(p[u].lc, tp);
if(r < ans1) query1(p[u].rc, tp);
} else {
if(r < ans1) query1(p[u].rc, tp);
if(l < ans1) query1(p[u].lc, tp);
}
}
void query2(int u, po tp) {
if(!u) return;
int now = dis(p[u].tp, tp);
if(ans2 < now) ans2 = now;
int l = -1, r = -1;
if(p[u].lc) l = calc2(p[u].lc, tp);
if(p[u].rc) r = calc2(p[u].rc, tp);
if(l > r) {
if(l > ans2) query2(p[u].lc, tp);
if(r > ans2) query2(p[u].rc, tp);
} else {
if(r > ans2) query2(p[u].rc, tp);
if(l > ans2) query2(p[u].lc, tp);
}
}
int minn = INF;
int main() {
cin >> n;
for(register int i = 1; i <= n; i++) read(t[i].a[0]), read(t[i].a[1]);
root = build(1, n, 0);
for(register int i = 1; i <= n; i++) {
ans1 = INF, ans2 = -INF;
query1(root, t[i]);
query2(root, t[i]);
minn = min(minn, ans2 - ans1);
}
cout << minn << endl;
return 0;
}
luoguP2479 [SDOI2010]捉迷藏的更多相关文章
- [SDOI2010]捉迷藏 K-Dtree
[SDOI2010]捉迷藏 链接 luogu 思路 k-dtree模板题 代码 #include <bits/stdc++.h> #define ls (t[u].ch[0]) #defi ...
- [SDOI2010]捉迷藏
嘟嘟嘟 k-d tree板儿题. 建完树后对每一个点求一遍最小和最大曼哈顿距离,是曼哈顿,不是欧几里得. #include<cstdio> #include<iostream> ...
- P2479 [SDOI2010]捉迷藏
传送门 KDtree是个吼东西啊-- 枚举每一个点,然后求出离他距离最远和最近的点的距离,更新答案 然而为什么感觉KDtree只是因为剪枝才能跑得动呢-- //minamoto #include< ...
- 模板—K-D-tree(P2479 [SDOI2010]捉迷藏)
#include<algorithm> #include<iostream> #include<cstdio> #include<cmath> #def ...
- 【题解】[SDOI2010]捉迷藏
题目链接:https://www.luogu.com.cn/problem/P2479 题目大意:求平面\(n\)个点中,到其它\(n-1\)个点的曼哈顿距离最大和最小距离之差最小的点,求出这个这个距 ...
- [学习笔记]K-D Tree
以前其实学过的但是不会拍扁重构--所以这几天学了一下 \(K-D\ Tree\) 的正确打开姿势. \(K\) 维 \(K-D\ Tree\) 的单次操作最坏时间复杂度为 \(O(k\times n^ ...
- KD-Tree总结
KD-Tree总结 问题引入 平面上有\(n\)个点,\(q\)组询问,每一次查询距离\((x,y)\)最近的点对,强制在线. 问题解决 暴力 显然我们可以直接枚举点然后算距离取\(min\),这样子 ...
- 2021.07.09 K-D树
2021.07.09 K-D树 前置知识 1.二叉搜索树 2.总是很长的替罪羊树 K-D树 建树 K-D树具有二叉搜索树的形态,对于每一个分类标准,小于标准的节点在父节点左边,大于标准的节点在父节点右 ...
- [BZOJ1941][Sdoi2010]Hide and Seek
[BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...
随机推荐
- jsp get 乱码
String str=request.getParameter("name");str=new String(str.getBytes("iso8859-1") ...
- S数据导入
一. 职责下的视图导入先对比UAT172和PROD 177的数据,若177比172多的数据进行删除,若172比177多的数据,重新加入到177. 1.删除177多余的 搜索一个177比172多的,进行 ...
- book pile SGU - 271
有n本书从上到下摞在一起,有两种操作.ADD(C)表示把一本新书C放到这一摞书的最顶上,ROTATE表示将前K本书进行反转.在一系列操作后输出最后书的顺序 分析: 当时听别人讲这个题的时候很懵逼,后来 ...
- HTML ISO-8859-1 参考手册(html字符转义)
HTML 4.01 支持 ISO 8859-1 (Latin-1) 字符集. ISO-8859-1 的较低部分(从 1 到 127 之间的代码)是最初的 7 比特 ASCII. ISO-8859-1 ...
- 新手教程: 如何在新浪云计算SAE里部署代码
感谢 sou6 的投递 时间:2011-11-22 来源:老夏博客 SAE自2011-7-10日起,全面支持SVN代码部署,用户不仅可以通过任何SVN客户端部署代码,而且SAE现有的代码部署方式也已经 ...
- HTTPS加密那点事--轻松秒懂HTTPS非对称加密
本文转载自微信公众号(苦逼的码农),原文地址: https://mp.weixin.qq.com/s/j-ss95ItMnWsZHLpUGBMkQ 用漫画的形式解释技术问题是不是有眼前一亮的感觉呢?以 ...
- String.getBytes()[转]
在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组.这个表示在不通OS下,返回的东西不一样! String.getBytes(String decode)方 ...
- Jedis连接Redis三种模式
这里说的三种工作模式是指: 1.单机模式 2.分片模式 3.集群模式(since 3.0) 说明图详见以下: 使用单机模式连接: private String addr="192.168.1 ...
- Spring Boot☞ 统一异常处理
效果区: 代码区: package com.wls.integrateplugs.exception.dto; public class ErrorInfo<T> { public st ...
- Redhat9.0+Apache1.3.29+Mysql3.23.58+PHP4.3.4
Redhat9.0+Apache1.3.29+Mysql3.23.58+PHP4.3.4 TAG标签: 摘要:红帽创建于1993年,是目前世界上最资深的Linux和开放源代码提供商,同时也是最获认可的 ...