• BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)


    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

    Solution

    $K-D~Tree$板子题……

    跑的有点慢于是加了波快读

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<algorithm>
      7 #define N (100009)
      8 #define INF (2000000000)
      9 using namespace std;
     10 
     11 int n,D,Root,tmp1,tmp2,ans=INF,LIM;
     12 
     13 inline int read()
     14 {
     15     int x=0,w=1; char c=getchar();
     16     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
     17     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
     18     return x*w;
     19 }
     20 
     21 struct Node
     22 {
     23     int ls,rs,d[2],Max[2],Min[2];
     24     bool operator < (const Node &a) const {return d[D]<a.d[D];}
     25 }p[N],Q;
     26 
     27 struct KDT
     28 {
     29     Node T[N];
     30     
     31     void Pushup(int now)
     32     {
     33         int ls=T[now].ls,rs=T[now].rs;
     34         for (int i=0; i<=1; ++i)
     35         {
     36             T[now].Max[i]=T[now].Min[i]=T[now].d[i];
     37             if (ls)
     38             {
     39                 T[now].Max[i]=max(T[now].Max[i],T[ls].Max[i]);
     40                 T[now].Min[i]=min(T[now].Min[i],T[ls].Min[i]);
     41             }
     42             if (rs)
     43             {
     44                 T[now].Max[i]=max(T[now].Max[i],T[rs].Max[i]);
     45                 T[now].Min[i]=min(T[now].Min[i],T[rs].Min[i]);
     46             }
     47         }
     48     }
     49     int Build(int opt,int l,int r)
     50     {
     51         if (l>r) return 0;
     52         int mid=(l+r)>>1;
     53         D=opt; nth_element(p+l,p+mid,p+r+1);
     54         T[mid]=p[mid];
     55         T[mid].ls=Build(opt^1,l,mid-1);
     56         T[mid].rs=Build(opt^1,mid+1,r);
     57         Pushup(mid); return mid;
     58     }
     59     int Get_Max(int now)
     60     {
     61         int ans=0;
     62         for (int i=0; i<=1; ++i)
     63             ans+=max(abs(Q.d[i]-T[now].Min[i]),abs(Q.d[i]-T[now].Max[i]));
     64         return ans;
     65     }
     66     int Get_Min(int now)
     67     {
     68         int ans=0;
     69         for (int i=0; i<=1; ++i)
     70         {
     71             ans+=max(0,T[now].Min[i]-Q.d[i]);
     72             ans+=max(0,Q.d[i]-T[now].Max[i]);
     73         }
     74         return ans;
     75     }
     76     void Query_Max(int now)
     77     {
     78         tmp1=max(tmp1,abs(Q.d[0]-T[now].d[0])+abs(Q.d[1]-T[now].d[1]));
     79         int ls=T[now].ls,rs=T[now].rs,lans=-INF,rans=-INF;
     80         if (ls) lans=Get_Max(ls);
     81         if (rs) rans=Get_Max(rs);
     82         if (lans<rans)
     83         {
     84             if (lans>tmp1) Query_Max(ls);
     85             if (rans>tmp1) Query_Max(rs);
     86         }
     87         else
     88         {
     89             if (rans>tmp1) Query_Max(rs);
     90             if (lans>tmp1) Query_Max(ls);
     91         }
     92     }
     93     void Query_Min(int now)
     94     {
     95         if (now!=LIM) tmp2=min(tmp2,abs(Q.d[0]-T[now].d[0])+abs(Q.d[1]-T[now].d[1]));
     96         int ls=T[now].ls,rs=T[now].rs,lans=INF,rans=INF;
     97         if (ls) lans=Get_Min(ls);
     98         if (rs) rans=Get_Min(rs);
     99         if (lans<rans)
    100         {
    101             if (lans<tmp2) Query_Min(ls);
    102             if (rans<tmp2) Query_Min(rs);
    103         }
    104         else
    105         {
    106             if (rans<tmp2) Query_Min(rs);
    107             if (lans<tmp2) Query_Min(ls);
    108         }
    109     }
    110 }KDT;
    111 
    112 int main()
    113 {
    114     scanf("%d",&n);
    115     for (int i=1; i<=n; ++i)
    116         scanf("%d%d",&p[i].d[0],&p[i].d[1]);
    117     Root=KDT.Build(0,1,n);
    118     for (int i=1; i<=n; ++i)
    119     {
    120         Q.d[0]=p[i].d[0]; Q.d[1]=p[i].d[1];
    121         LIM=i;
    122         tmp1=-INF; tmp2=INF;
    123         KDT.Query_Max(Root);
    124         KDT.Query_Min(Root);
    125         ans=min(ans,tmp1-tmp2);
    126     }
    127     printf("%d
    ",ans);
    128 }
  • 相关阅读:
    HDU2647(拓扑排序+反向建图)
    Android Activity之间通信
    Swift 编程语言学习0.1——Swift简单介绍
    HDU 5012 Dice (BFS)
    当向后台插入或读取JSON数据遇见回车时
    Android CTS測试Fail项改动总结(四)
    【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头
    android蓝牙4.0(BLE)开发之ibeacon初步
    Error opening zip file or JAR manifest missing : D:play-1.2.5/framework/play-1.2.5.jar
    Codeforces Round #256 (Div. 2)——Multiplication Table
  • 原文地址:https://www.cnblogs.com/refun/p/10151332.html
Copyright © 2020-2023  润新知