zoukankan      html  css  js  c++  java
  • 【BZOJ-1941】Hide and Seek KD-Tree

    1941: [Sdoi2010]Hide and Seek

    Time Limit: 16 Sec  Memory Limit: 162 MB
    Submit: 830  Solved: 455
    [Submit][Status][Discuss]

    Description

    小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏。 但是,他们觉得,玩普通的捉迷藏没什么意思,还是不够寂寞,于是,他们决定玩寂寞无比的螃蟹版捉迷藏,顾名思义,就是说他们在玩游戏的时候只能沿水平或垂直方向走。一番寂寞的剪刀石头布后,他们决定iPig去捉giPi。由于他们都很熟悉PKU的地形了,所以giPi只会躲在PKU内n个隐秘地点,显然iPig也只会在那n个地点内找giPi。游戏一开始,他们选定一个地点,iPig保持不动,然后giPi用30秒的时间逃离现场(显然,giPi不会呆在原地)。然后iPig会随机地去找giPi,直到找到为止。由于iPig很懒,所以他到总是走最短的路径,而且,他选择起始点不是随便选的,他想找一个地点,使得该地点到最远的地点和最近的地点的距离差最小。iPig现在想知道这个距离差最小是多少。 由于iPig现在手上没有电脑,所以不能编程解决这个如此简单的问题,所以他马上打了个电话,要求你帮他解决这个问题。iPig告诉了你PKU的n个隐秘地点的坐标,请你编程求出iPig的问题。

    Input

    第一行输入一个整数N 第2~N+1行,每行两个整数X,Y,表示第i个地点的坐标

    Output

    一个整数,为距离差的最小值。

    Sample Input

    4
    0 0
    1 0
    0 1
    1 1

    Sample Output

    1

    HINT

    对于30%的数据,N<=1000 对于100%的数据,N<=500000,0<=X,Y<=10^8 保证数据没有重点保证N>=2

    Source

    SDOI2010 第二轮Day 1

    Solution

    KDTree模板题...把所有点加入KDTree中,再枚举每一个点,找最远最近,并更新答案即可

    需要注意的是,计算最远和最近的两个分开写,而且计算最近点的时候不能计算到自己

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-')f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f; 
    }
    #define inf 0x7fffffff
    #define maxn 500010
    int n,D,ans;
    struct PointNode
    {
        int l,r; int d[2],maxx[2],minn[2];
        PointNode (int x=0,int y=0) {l=r=0; d[0]=x,d[1]=y;}
        bool operator < (const PointNode & A) const {return d[D]<A.d[D];}
    }p[maxn];
    int dis(PointNode A,PointNode B) {return abs(A.d[1]-B.d[1])+abs(A.d[0]-B.d[0]);}
    struct KDTreeNode
    {
        PointNode tree[maxn<<1],Point;
        int rt,ansMax,ansMin;
        void Update(int now)
            {
                for (int i=0; i<=1; i++)
                    {
                        tree[now].minn[i]=tree[now].maxx[i]=tree[now].d[i];
                        if (tree[now].l)
                            tree[now].minn[i]=min(tree[tree[now].l].minn[i],tree[now].minn[i]),
                  tree[now].maxx[i]=max(tree[tree[now].l].maxx[i],tree[now].maxx[i]); if (tree[now].r) tree[now].minn[i]=min(tree[tree[now].r].minn[i],tree[now].minn[i]),
                  tree[now].maxx[i]=max(tree[tree[now].r].maxx[i],tree[now].maxx[i]); } } int BuildTree(int l,int r,int dd) { int mid=(l+r)>>1; D=dd; nth_element(p+l,p+mid,p+r+1); tree[mid]=p[mid]; for (int i=0; i<=1; i++) tree[mid].minn[i]=tree[mid].maxx[i]=tree[mid].d[i]; if (l<mid) tree[mid].l=BuildTree(l,mid-1,dd^1); if (r>mid) tree[mid].r=BuildTree(mid+1,r,dd^1); Update(mid); return mid; } int disMax(int now) { if (!now) return -inf; int re=0; for (int i=0; i<=1; i++) re+=max(abs(tree[now].maxx[i]-Point.d[i]),abs(tree[now].minn[i]-Point.d[i])); return re; } int disMin(int now) { if (!now) return inf; int re=0; for (int i=0; i<=1; i++) re+=max(0,tree[now].minn[i]-Point.d[i]); for (int i=0; i<=1; i++) re+=max(0,Point.d[i]-tree[now].maxx[i]); return re; } void GetMax(int now) { if (!now) return; int dl,dr,d0; d0=dis(tree[now],Point); ansMax=max(d0,ansMax); if (tree[now].l) dl=disMax(tree[now].l); if (tree[now].r) dr=disMax(tree[now].r); if (dl>dr) { if (dl>ansMax) GetMax(tree[now].l); if (dr>ansMax) GetMax(tree[now].r); } else { if (dr>ansMax) GetMax(tree[now].r); if (dl>ansMax) GetMax(tree[now].l); } } void GetMin(int now) { if (!now) return; int dl,dr,d0; d0=dis(tree[now],Point); if (d0) ansMin=min(ansMin,d0); if (tree[now].l) dl=disMin(tree[now].l); if (tree[now].r) dr=disMin(tree[now].r); if (dl<dr) { if (dl<ansMin) GetMin(tree[now].l); if (dr<ansMin) GetMin(tree[now].r); } else { if (dr<ansMin) GetMin(tree[now].r); if (dl<ansMin) GetMin(tree[now].l); } } int QueryMax(PointNode P) {Point=P; ansMax=-inf; GetMax(rt); return ansMax;} int QueryMin(PointNode P) {Point=P; ansMin=inf; GetMin(rt); return ansMin;} }KDTree; int main() { n=read(); for (int x,y,i=1; i<=n; i++) x=read(),y=read(),p[i].d[0]=x,p[i].d[1]=y; for (int i=0; i<=1; i++) p[0].maxx[i]=-inf,p[0].minn[i]=inf; KDTree.rt=KDTree.BuildTree(1,n,1); ans=inf; for (int i=1; i<=n; i++) { int minn=KDTree.QueryMin(p[i]),maxx=KDTree.QueryMax(p[i]); ans=min(ans,maxx-minn); } printf("%d ",ans); return 0; }
  • 相关阅读:
    Vue+Element-UI+jQuery+Layer+Camera+Easing的简单应用
    Vue(vue-cli脚手架)中使用layer.js做非模态弹窗(二)
    unicable
    grep 搜索目录时,怎样排除某些目录?
    Mali Midgard架构解析
    如何从GFP确定最后申请的内存来自哪个zone?
    内存申请 GFP_KERNEL GFP_ATOMIC
    Linux内核中的page migration和compaction机制简介
    IOVA/IOMMU
    memory zone spanned/present/managed区别
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5533319.html
Copyright © 2011-2022 走看看