HYSBZ bzoj 1941 Hide and Seek
来源:互联网 发布:java项目开发源代码 编辑:程序博客网 时间:2024/06/16 03:07
Problem
www.lydsy.com/JudgeOnline/problem.php?id=1941
vjudge.net/contest/187908#problem/B
Reference
[BZOJ1941][Sdoi2010]Hide and Seek(kd-tree)
Meaning
给出平面上 n 个点,要选其中一个,使得它到其它点的 曼哈顿最远距离和最近距离的差 最小,求这个最小的差。
Analysis
用 K-D树对每个点都求离它最远的点和最近的点的距离,相减更新答案。
Notes
这题集合了 K-D树求最远点和最近点的套路,主要在于那两个估价减枝。
在建树的时候,处理出每个点划分的那个区域里的横、纵坐标的最大、最小值,相当于找到包住这个区域的那个大矩形。
在最远点估价的时候,相当于用这个矩形的四个顶点之一(离目标点最远那个)来估价;在最近点时,相当于判断目标点在不在这个矩形内,如果在,直接不算距离,(某一维)在矩形外才算上目标点(在该维度)离最近的矩形边界的距离。
Code
#include <cmath>#include <algorithm>#include <iostream>using namespace std;const int N = 500000, D = 2, X = 1e8, Y = X;int idx;struct node{ int v[D]; bool operator < (const node &rhs) const { return v[idx] < rhs.v[idx]; }} kdt[N], aim;int lc[N], rc[N], big[N][D], sml[N][D];void pushup(int p){ for(int i = 0; i < D; ++i) { int &b = big[p][i], &s = sml[p][i]; if(~lc[p]) { b = max(b, big[lc[p]][i]); s = min(s, sml[lc[p]][i]); } if(~rc[p]) { b = max(b, big[rc[p]][i]); s = min(s, sml[rc[p]][i]); } }}int build(int l, int r, int d){ idx = d & 1; int m = l + r >> 1; nth_element(kdt + l, kdt + m, kdt + r + 1); lc[m] = rc[m] = -1; for(int i = 0; i < D; ++i) big[m][i] = sml[m][i] = kdt[m].v[i]; if(l < m) lc[m] = build(l, m - 1, d + 1); if(r > m) rc[m] = build(m + 1, r, d + 1); pushup(m); return m;}inline int manhattan(int p){ return abs(aim.v[0] - kdt[p].v[0]) + abs(aim.v[1] - kdt[p].v[1]);}int far, near; // 最远距离、最近距离/* 最远距离的估价 */int dis_b(int p){ int res = 0; for(int i = 0; i < D; ++i) res += max( abs(aim.v[i] - big[p][i]), abs(aim.v[i] - sml[p][i]) ); return res;}void query_b(int p){ far = max(far, manhattan(p)); int dl = 0, dr = 0; if(~lc[p]) dl = dis_b(lc[p]); if(~rc[p]) dr = dis_b(rc[p]); if(dl > dr) { if(dl > far) query_b(lc[p]); if(dr > far) query_b(rc[p]); } else { if(dr > far) query_b(rc[p]); if(dl > far) query_b(lc[p]); }}/* 最近距离的估价 */int dis_s(int p){ int res = 0; for(int i = 0; i < D; ++i) if(aim.v[i] > big[p][i]) // 超出上边界 res += aim.v[i] - big[p][i]; else if(aim.v[i] < sml[p][i]) // 超出下边界 res += sml[p][i] - aim.v[i]; return res;}void query_s(int p){ // 最近距离不包括到自己的距离 if(int d = manhattan(p)) near = min(near, d); int dl = X + Y, dr = X + Y; if(~lc[p]) dl = dis_s(lc[p]); if(~rc[p]) dr = dis_s(rc[p]); if(dl < dr) { if(dl < near) query_s(lc[p]); if(dr < near) query_s(rc[p]); } else { if(dr < near) query_s(rc[p]); if(dl < near) query_s(lc[p]); }}int main(){ ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; for(int i = 0; i < n; ++i) cin >> kdt[i].v[0] >> kdt[i].v[1]; int rt = build(0, n - 1, 0), ans = X + Y; for(int i = 0; i < n; ++i) { aim = kdt[i]; far = 0; near = X + Y; query_b(rt); query_s(rt); ans = min(ans, far - near); } cout << ans << '\n'; return 0;}
阅读全文
0 0
- HYSBZ bzoj 1941 Hide and Seek
- bzoj-1941 Hide and Seek
- [BZOJ 1941]Hide and Seek
- 【54.08%】【BZOJ 1941】Hide and Seek
- bzoj 1941: [Sdoi2010]Hide and Seek KDtree
- BZOJ 1941 [Sdoi2010] Hide and Seek
- BZOJ 1941: [Sdoi2010]Hide and Seek kdtree
- BZOJ 1941 SDOI 2010 Hide and Seek K-D树
- BZOJ 1941 Sdoi2010 Hide and Seek K-Dimensional-Tree
- [KD-TREE] BZOJ 1941 [Sdoi2010]Hide and Seek
- bzoj 1941: [Sdoi2010]Hide and Seek (KD-tree)
- 【BZOJ 1941】[Sdoi2010]Hide and Seek kd-tree
- 1941: [Sdoi2010]Hide and Seek
- 【K-D树 求最近最远距离】BZOJ 1941 [Sdoi2010]Hide and Seek
- BZOJ 3402: [Usaco2009 Open]Hide and Seek 捉迷藏 最短路
- bzoj 3402: [Usaco2009 Open]Hide and Seek 捉迷藏
- 躲猫猫 hide-and-seek
- HYSBZ1941-Hide and Seek
- tf.random_uniform的使用
- git --- If no other git process is currently running, this probably means a git process crashed in
- Kylin 之对大数据量的多维分析
- iPhone X App 页面适配
- 能力糟糕的程序员日记第一 二天
- HYSBZ bzoj 1941 Hide and Seek
- ANSI Common Lisp译本笔记6
- java实现发送邮件
- 盒子模型之美容热点产品
- 搭建https
- C++ 双向队列链式实现和队列的顺序实现
- ubunt学习1
- 以C语言的方式理解IIC总线
- Django REST FrameWork中文教程3:基于类的视图