zoukankan      html  css  js  c++  java
  • 【kd-tree】bzoj1941 [Sdoi2010]Hide and Seek

    枚举每个点,计算离他最近的和最远的点。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define N 500001
    #define INF 2147483647
    #define KD 2//ά¶ÈÊý
    int qp[KD],disn,disx;
    int n,root;
    bool dn;
    struct Node
    {
        int minn[KD],maxx[KD],p[KD];
        int ch[2];
        void Init()
          {
            for(int i=0;i<KD;++i)
              minn[i]=maxx[i]=p[i];
          }
        int Disn()
          {
            int res=0;
            for(int i=0;i<KD;++i)
              {
                res+=max(0,minn[i]-qp[i]);
                res+=max(0,qp[i]-maxx[i]);
              }
            return res;
          }
        int Disx()
          {
            int res=0;
            for(int i=0;i<KD;++i)
              {
                res+=max(0,qp[i]-minn[i]);
                res+=max(0,maxx[i]-qp[i]);
              }
            return res;
          }
    }T[N];
    void Update(int rt)
    {
        for(int i=0;i<2;++i)
          if(T[rt].ch[i])
            for(int j=0;j<KD;++j)
              {
                T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
                T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
              }
    }
    int Abs(const int &x){return x<0 ? (-x) : x;}
    int Dis(int a[],int b[]){return Abs(a[0]-b[0])+Abs(a[1]-b[1]);}
    bool operator < (const Node &a,const Node &b){return a.p[dn]<b.p[dn];}
    int Buildtree(int l=1,int r=n,bool d=0)
    {
        dn=d;
        int m=(l+r>>1);
        nth_element(T+l,T+m,T+r+1);
        T[m].Init();
        if(l!=m) T[m].ch[0]=Buildtree(l,m-1,d^1);
        if(m!=r) T[m].ch[1]=Buildtree(m+1,r,d^1);
        Update(m);
        return m;
    }
    int I=1;
    void Queryn(int rt=root)
    {
        if(rt!=I)
          disn=min(disn,Dis(T[rt].p,qp));
        int dd[2];
        for(int i=0;i<2;i++)
          if(T[rt].ch[i])
            dd[i]=T[T[rt].ch[i]].Disn();
          else dd[i]=INF;
        bool f=(dd[0]<=dd[1]);
        if(dd[!f]<disn && T[rt].ch[!f]) Queryn(T[rt].ch[!f]);
        if(dd[f]<disn && T[rt].ch[f]) Queryn(T[rt].ch[f]);
    }
    void Queryx(int rt=root)
    {
        if(rt!=I)
          disx=max(disx,Dis(T[rt].p,qp));
        int dd[2];
        for(int i=0;i<2;i++)
          if(T[rt].ch[i])
            dd[i]=T[T[rt].ch[i]].Disx();
          else dd[i]=-INF;
        bool f=(dd[0]>=dd[1]);
        if(dd[!f]>disx && T[rt].ch[!f]) Queryx(T[rt].ch[!f]);
        if(dd[f]>disx && T[rt].ch[f]) Queryx(T[rt].ch[f]);
    }
    int ans=INF;
    int main()
    {
    //  freopen("bzoj1941.in","r",stdin);
    //  freopen("bzoj2716.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
          scanf("%d%d",&T[i].p[0],&T[i].p[1]);
        root=(1+n>>1);
        Buildtree();
        for(;I<=n;++I)
          {
            disn=INF;
            disx=0;
            qp[0]=T[I].p[0];
            qp[1]=T[I].p[1];
            Queryn();
            Queryx();
            ans=min(ans,disx-disn);
          }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
    数组模拟栈(C语言)
    JDBC数据源连接池的配置和使用实例
    servlet 具体实现
    MySQL查询数据表中数据记录(包括多表查询)
    java开发中的23中设计模式
    eclipse使用和优化配置
    将博客搬至CSDN
    itext poi 学习之旅 (3)读取数据库信息并由excel展现出来
    itext poi 学习之旅 (2)创建excel
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587122.html
Copyright © 2011-2022 走看看