[BZOJ 1941]Hide and Seek

来源:互联网 发布:长波电台事件 知乎 编辑:程序博客网 时间:2024/05/22 09:05

K-D tree

注意得到最大最小值的距离计算函数


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 500010using namespace std;int n, D;void read(int& num){num = 0;int f = 1;char ch = getchar();for(; ch < '!'; ch = getchar());if(ch == '-'){ch = getchar();f = -1;}for(; ch > '!'; ch = getchar())num = num * 10 + ch - 48;num *= f;}struct Point{int mn[2], mx[2], d[2], l, r;int& operator[](int i){return d[i];}void InState(){read(d[0]), read(d[1]);l = r = 0;}bool operator<(Point k)const{return d[D] < k.d[D];}}t[maxn << 1];int ans[maxn];const int inf = 0x7fffffff;namespace KDtree{int root, ans;Point P;#define L(p) t[p].l#define R(p) t[p].rvoid update(int p){for(int i = 0; i < 2; i ++){t[p].mn[i] = t[p].mx[i] = t[p].d[i];if(L(p)){t[p].mn[i] = min(t[p].mn[i], t[L(p)].mn[i]);t[p].mx[i] = max(t[p].mx[i], t[L(p)].mx[i]);}if(R(p)){t[p].mn[i] = min(t[p].mn[i],  t[R(p)].mn[i]);t[p].mx[i] = max(t[p].mx[i],  t[R(p)].mx[i]);}}}int build(int l, int r, int now){if(l > r)return 0;int mid = l + r >> 1;D = now;nth_element(t + l, t + mid, t + r + 1);L(mid) = build(l, mid - 1, now ^ 1);R(mid) = build(mid + 1, r, now ^ 1);update(mid);return mid;}int Abs(int x){return x > 0 ? x : -x;}int dis(Point k){int ret = 0;for(int i = 0; i < 2; i ++)ret += Abs(k[i] - P[i]);return ret;}int dist_mn(const Point& k){int ret = 0;for(int i = 0; i < 2; i ++)            ret += max(P[i] - k.mx[i], k.mn[i] - P[i]);return ret;}int dist_mx(const Point& k){int ret = 0;for(int i = 0; i < 2; i ++)    ret += max(k.mx[i] - P[i], P[i] - k.mn[i]);return ret;}void ask_mx(int root, int now){if(!root)return;int dl = -inf, dr = -inf;int d = dis(t[root]);ans = max(ans, d);if(L(root))dl = dist_mx(t[L(root)]);if(R(root))dr = dist_mx(t[R(root)]);if(dl > dr){if(dl > ans)ask_mx(L(root), now ^ 1);if(dr > ans)ask_mx(R(root), now ^ 1);}else{if(dr > ans)ask_mx(R(root), now ^ 1);if(dl > ans)ask_mx(L(root), now ^ 1);}}void ask_mn(int root, int now){int dl = inf, dr = inf;int d = dis(t[root]);if(d)ans = min(ans, d);if(L(root))dl = dist_mn(t[L(root)]);if(R(root))dr = dist_mn(t[R(root)]);if(dl < dr){if(dl < ans)ask_mn(L(root), now ^ 1);if(dr < ans)ask_mn(R(root), now ^ 1);}else{if(dr < ans)ask_mn(R(root), now ^ 1);if(dl < ans)ask_mn(L(root), now ^ 1);}}}int main(){#ifndef ONLINE_JUDGEfreopen("1941.in", "r", stdin);freopen("1941.out", "w", stdout);#endifread(n);for(int i = 1; i <= n; i ++)    t[i].InState();KDtree:: root = KDtree:: build(1, n, 0);int ret = inf;for(int i = 1; i <= n; i ++){        KDtree::P = t[i];        KDtree::ans = 0;KDtree::ask_mx(KDtree::root, 0);ans[i] = KDtree::ans;KDtree::ans = inf;KDtree::ask_mn(KDtree::root, 0);ans[i] -= KDtree::ans;ret = min(ret, ans[i]);}printf("%d\n", ret);    return 0;}


0 0
原创粉丝点击