博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
luoguP2479 [SDOI2010]捉迷藏
阅读量:6406 次
发布时间:2019-06-23

本文共 3006 字,大约阅读时间需要 10 分钟。

据说可以用线段树做但是我不会,只能写一个 KD-Tree 了

对于每个点求出距离它最远的点和最近的点的距离,然后取 min 即可

因为这个东西是可以剪枝的,所以跑的挺快的

#include 
#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
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;}

转载于:https://www.cnblogs.com/LJC00118/p/9747746.html

你可能感兴趣的文章
第七次作业
查看>>
Oracle中NVARCHAR2与VARCHAR2的区别
查看>>
php debug
查看>>
新的一天,新的开始。
查看>>
<img> <a> CSS
查看>>
JS call和apply方法使用
查看>>
使用JavaScript设置、获取父子页面中的值
查看>>
在vue中如何实现购物车checkbox的三级联动
查看>>
华为C8812 手机连接电脑的问题
查看>>
Python3-装饰器
查看>>
读《More Effective C++中文版》笔记
查看>>
Elementui实战知识点随记
查看>>
Oracle10g RAC 修改IP [转载]
查看>>
关于char p[] = "hello world"; char *p = "hello world";
查看>>
FIREDAC的心得
查看>>
NPOI批量导入大量数据
查看>>
了解 Windows Azure 存储计费 – 带宽、事务和容量
查看>>
mysql5.7.22 zip 版安装
查看>>
【题解】最大公约数之和 V3 51nod 1237 杜教筛
查看>>
架构师速成6.7-设计开发思路-uml 分类: 架构师速成 ...
查看>>