【K-D树 求最近最远距离】BZOJ 1941 [Sdoi2010]Hide and Seek
来源:互联网 发布:见过好听的名字 知乎 编辑:程序博客网 时间:2024/05/25 19:57
Problem Description
给你n个点(二维),让你求所有点 到最远点 和最近点 的距离差最小
思路:
自身点不算。
求个距离该点,最近距离。和 距离该点,最远距离即可。
这里的距离指的是 曼哈顿距离
#include<bits/stdc++.h>using namespace std;const int MAX = 500010;const int inf = 0x3f3f3f3f;const int DIM = 2;struct node{ int l, r; int d[DIM], maxn[DIM], minn[DIM]; inline void maintain()//初始化 { l = r = 0; for(int i = 0; i < DIM; i++) maxn[i] = minn[i] = d[i]; }}tree[MAX];int D;bool operator < (const node &a, const node &b)//重载,从小到大{ return a.d[D] < b.d[D];}inline void Merge(int mid)//归并,向上更新{ int son[2] = {tree[mid].l, tree[mid].r}; for(int i = 0; i < 2; i++) { if(!son[i]) continue; for(int j = 0; j < DIM; j++) { tree[mid].maxn[j] = max(tree[mid].maxn[j], tree[son[i]].maxn[j]); tree[mid].minn[j] = min(tree[mid].minn[j], tree[son[i]].minn[j]); } }}int build(int l, int r, int now)//建树{ int mid = (l+r) >> 1; D = now; nth_element(tree+l, tree+mid, tree+r+1);//对于now维,以mid为中间,左边都是比它小,右边都是比它大。 tree[mid].maintain();//初始化 if(l < mid) tree[mid].l = build(l, mid-1, (now+1)%DIM); if(r > mid) tree[mid].r = build(mid+1, r, (now+1)%DIM); Merge(mid); return mid;}int ans1, ans2;int partionMin(int o, int k)//求最小可能值{ int red = 0; for(int i = 0; i < DIM; i++) { if(tree[k].d[i] > tree[o].maxn[i]) red += tree[k].d[i] - tree[o].maxn[i]; if(tree[k].d[i] < tree[o].minn[i]) red += tree[o].minn[i] - tree[k].d[i]; } return red;}int partionMax(int o, int k)//求最大可能值{ int red = 0; for(int i = 0; i < DIM; i++) { red += max(abs(tree[k].d[i] - tree[o].maxn[i]), abs(tree[k].d[i] - tree[o].minn[i])); } return red;}void queryMin(int o, int k)//求最小距离{ int dm = abs(tree[k].d[0] - tree[o].d[0]) + abs(tree[k].d[1] - tree[o].d[1]); if(o == k) dm = inf;//自身点不算。 if(ans1 > dm) ans1 = dm; int dl = tree[o].l ? partionMin(tree[o].l, k) : inf; int dr = tree[o].r ? partionMin(tree[o].r, k) : inf; if(dl < dr) { if(dl < ans1) queryMin(tree[o].l, k); if(dr < ans1) queryMin(tree[o].r, k); } else { if(dr < ans1) queryMin(tree[o].r, k); if(dl < ans1) queryMin(tree[o].l, k); }}void queryMax(int o, int k)//求最大距离{ int dm = abs(tree[k].d[0] - tree[o].d[0]) + abs(tree[k].d[1] - tree[o].d[1]); if(ans2 < dm) ans2 = dm; int dl = tree[o].l ? partionMax(tree[o].l, k) : 0; int dr = tree[o].r ? partionMax(tree[o].r, k) : 0; if(dl > dr) { if(dl > ans2) queryMax(tree[o].l, k); if(dr > ans2) queryMax(tree[o].r, k); } else { if(dr > ans2) queryMax(tree[o].r, k); if(dl > ans2) queryMax(tree[o].l, k); }}int main(){ int n, i, j; while(~scanf("%d", &n)) { for(i = 1; i <= n; i++) for(j = 0; j < DIM; j++) scanf("%d", &tree[i].d[j]); int root = build(1, n, 0); int Ans; for(i = 1; i <= n; i++) { ans1 = inf; ans2 = 0; queryMin(root, i); queryMax(root, i); Ans = min(Ans, ans2 - ans1); } printf("%d\n", Ans); }}
阅读全文
0 0
- 【K-D树 求最近最远距离】BZOJ 1941 [Sdoi2010]Hide and Seek
- BZOJ 1941 Sdoi2010 Hide and Seek K-Dimensional-Tree
- 1941: [Sdoi2010]Hide and Seek|K-D Tree
- 1941: [Sdoi2010]Hide and Seek K-D tree
- BZOJ 1941 SDOI 2010 Hide and Seek K-D树
- bzoj 1941: [Sdoi2010]Hide and Seek KDtree
- BZOJ 1941 [Sdoi2010] Hide and Seek
- BZOJ 1941: [Sdoi2010]Hide and Seek kdtree
- Bzoj1941:[Sdoi2010]Hide and Seek:K-D-Tree
- 1941: [Sdoi2010]Hide and Seek
- [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|动态加点线段树
- 【bzoj1941】【sdoi2010】【Hide and Seek】【kd树】
- bzoj-1941 Hide and Seek
- [BZOJ 1941]Hide and Seek
- [BZOJ1941][Sdoi2010]Hide and Seek
- 函数调用约定
- java-collection(集合)
- 兼容
- 某网站的一己之见
- git添加公钥后报错sign_and_send_pubkey: signing failed: agent refused operation的解决办法
- 【K-D树 求最近最远距离】BZOJ 1941 [Sdoi2010]Hide and Seek
- ubuntu16交叉编译Qt5.9
- ExecutorService 的理解与使用
- Python 性能优化
- 介绍一下Spring Cloud简介
- javascript学习(十八)— jQuery选择器(二)
- 软件调试笔记29
- notepad++ 根据文件内容查找文件
- 输入输出系统(四)