BZOJ 1941 SDOI 2010 Hide and Seek K-D树

题目大意:给出平面上n个点,一个点离所有点的最长距离和最短距离的差最小,求这个最小的差。

思路:50W的数据为何O(nsqrt(n))的暴力能过???

CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 500010
#define INF 0x3f3f3f3f
using namespace std;
#define min(a,b) ((a) < (b) ? (a):(b))
#define max(a,b) ((a) > (b) ? (a):(b))

int dim;

struct Point{
    int x,y;

    Point(int _,int __):x(_),y(__) {}
    Point() {}
    bool operator <(const Point &a)const {
        return dim ? x < a.x:y < a.y;
    }
    void Read() {
        scanf("%d%d",&x,&y);
    }
}point[MAX];

inline int Calc(const Point &p1,const Point &p2)
{
    return abs(p1.x - p2.x) + abs(p1.y - p2.y);
}

struct KDTree{
    KDTree *son[2];
    Point root;
    int x0,y0,x1,y1;

    KDTree(KDTree *_,KDTree *__,Point ___) {
        son[0] = _,son[1] = __;
        root = ___;
        x0 = x1 = ___.x;
        y0 = y1 = ___.y;
    }
    KDTree() {}
    void Maintain(KDTree *a) {
        x0 = min(x0,a->x0);
        x1 = max(x1,a->x1);
        y0 = min(y0,a->y0);
        y1 = max(y1,a->y1);
    }
    int DisMin(const Point &p) {
        int re = 0;
        if(p.x < x0) re += x0 - p.x;
        if(p.x > x1) re += p.x - x1;
        if(p.y < y0) re += y0 - p.y;
        if(p.y > y1) re += p.y - y1;
        return re;
    }
    int DisMax(const Point &p) {
        int re = 0;
        re += max(abs(p.x - x0),abs(p.x - x1));
        re += max(abs(p.y - y0),abs(p.y - y1));
        return re;
    }
}*root,none,*nil = &none;

int cnt;

KDTree *BuildTree(int l,int r,int d)
{
    if(l > r)    return nil;
    dim = d;
    int mid = (l + r) >> 1;
    nth_element(point + l,point + mid,point + r + 1);
    KDTree *re = new KDTree(BuildTree(l,mid - 1,!d),BuildTree(mid + 1,r,!d),point[mid]);
    if(re->son[0] != nil)    re->Maintain(re->son[0]);
    if(re->son[1] != nil)    re->Maintain(re->son[1]);
    return re;
}

int _min,_max;

void AskMin(KDTree *a,const Point &p)
{
    int dis = Calc(a->root,p);
    if(dis) _min = min(_min,dis);
    int l = a->son[0] == nil ? INF:a->son[0]->DisMin(p);
    int r = a->son[1] == nil ? INF:a->son[1]->DisMin(p);
    if(l < r) {
        if(a->son[0] != nil) AskMin(a->son[0],p);
        if(a->son[1] != nil && r <= _min) AskMin(a->son[1],p);
    }
    else {
        if(a->son[1] != nil) AskMin(a->son[1],p);
        if(a->son[0] != nil && l <= _min) AskMin(a->son[0],p);
    }
}

void AskMax(KDTree *a,const Point &p)
{
    int dis = Calc(a->root,p);
    _max = max(_max,dis);
    int l = a->son[0] == nil ? -INF:a->son[0]->DisMax(p);
    int r = a->son[1] == nil ? -INF:a->son[1]->DisMax(p);
    if(l > r) {
        if(a->son[0] != nil) AskMax(a->son[0],p);
        if(a->son[1] != nil && r >= _max) AskMax(a->son[1],p);
    }
    else {
        if(a->son[1] != nil) AskMax(a->son[1],p);
        if(a->son[0] != nil && l >= _max) AskMax(a->son[0],p);
    }
}

int main()
{
    cin >> cnt;
    for(int i = 1; i <= cnt; ++i)
        point[i].Read();
    root = BuildTree(1,cnt,0);
    int ans = INF;
    for(int i = 1; i <= cnt; ++i) {
        _min = INF,_max = -INF;
        AskMin(root,point[i]);
        AskMax(root,point[i]);
        ans = min(ans,_max - _min);
    }
    cout << ans << endl;
    return 0;
}

时间: 2024-08-10 15:07:35

BZOJ 1941 SDOI 2010 Hide and Seek K-D树的相关文章

BZOJ 3402: [Usaco2009 Open]Hide and Seek 捉迷藏

题目 3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MB Description 贝茜在和约翰玩一个“捉迷藏”的游戏. 她正要找出所有适合她躲藏的安全牛棚.一共有N(2≤N≤20000)个牛棚,被编为1到N号.她知道约翰(捉牛者)从牛棚1出发.所有的牛棚由M(1≤M≤50000)条双向路连接,每条双向路连接两个不同的牛棚.所有的牛棚都是相通的.贝茜认为同牛棚1距离最远的的牛棚是安全的.两个

BZOJ 1975 SDOI 2010 魔法猪学院 A*求K短路

题目大意:给出一张无向图,给出一个数值m,求出从1到N的前k短路的长度和>=数值m. 思路:注意!不能使用priority_queue,否则你会死的很惨..为了解惑,我去找了当年SD省选的原题,分明空间是256M,为什么BZOJ和BASHUOJ上都是64M??卡pq有意思么??? 思路很简单,就是按顺序求出这张图的前k短路,然后当m减成负数的时候就返回. CODE: #include <queue> #include <cstdio> #include <cstring

【数学/扩展欧几里得/Lucas定理】BZOJ 1951 :[Sdoi 2010]古代猪文

Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃花源了.猪

BZOJ 1927 SDOI 2010 星际竞速 费用流

题目大意:宇宙空间中进行了一次竞速大赛.有两种飞行方式,第一种是通过正常的道路,但是只能从标号小的飞到标号大的地方:第二种是直接过去,但是需要花费固定的时间.问正好遍历一次所有的点最少需要的多少时间. 思路:费用流.把每个点拆点,S到每个点的起点连费用0的边,向每个终点连费用为固定费用的边,图中原有的边从一个的起点连到另一个点的终点.然后每个点的终点向T连边.跑最小费用最大流就是最后的答案. CODE: #include <queue> #include <cstdio> #inc

【BZOJ】【1941】【SDOI2010】Hide and Seek

KD-Tree 一开始看错题了 其实是:给定n个点,从中找一个点,使得其他所有点到它距离的最大值与最小值之差最小. 利用KD-Tree暴力求出每个点的答案(找离它最近的点以及最远的点(当然只关心距离)) 然后……两个过程分开写…… 注意一下最近的点的距离不能是0(然而我一开始用 if (o==tmp) return INF; 就WA了……)(这里o是当前搜索到的点,tmp是枚举的起始点) 1 /***************************************************

bzoj:1941: [Sdoi2010]Hide and Seek

1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 531  Solved: 295[Submit][Status][Discuss] Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是

3402: [Usaco2009 Open]Hide and Seek 捉迷藏

3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 78  Solved: 64[Submit][Status] Description 贝茜在和约翰玩一个“捉迷藏”的游戏. 她正要找出所有适合她躲藏的安全牛棚.一共有N(2≤N≤20000)个牛棚,被编为1到N号.她知道约翰(捉牛者)从牛棚1出发.所有的牛棚由M(1≤M≤50000)条双向路连接,每条双向路连接两个不同的牛棚

【BZOJ-1941】Hide and Seek KD-Tree

1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 830  Solved: 455[Submit][Status][Discuss] Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏. 但是,他们觉得,玩普通的捉迷藏没什么意思,还是

Luogu 2951 捉迷藏Hide and Seek

P2951 [USACO09OPEN]捉迷藏Hide and Seek 题目描述 Bessie is playing hide and seek (a game in which a number of players hide and a single player (the seeker) attempts to find them after which various penalties and rewards are assessed; much fun usually ensues)