zoukankan      html  css  js  c++  java
  • bzoj 1941 [Sdoi2010]Hide and Seek——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1941

    第二道KDtree!

    枚举每个点,求出距离它的最远和最近距离。O( n * logn )。

    曼哈顿最小估价:max( 0 , s[ cr ].x[ 0 ] - a[ k ].p[ 0 ] ) + max( 0 , a[ k ].p[ 0 ] - s[ cr ].y[ 0 ] ) + max( 0 , s[ cr ].x[ 1 ] - a[ k ].p[ 1 ] ) + max( 0 , a[ k ].p[ 1 ] - s[ cr ].y[ 1 ] ) 。

    曼哈顿最大估价:max( abs( s[ cr ].x[ 0 ] - a[ k ].p[ 0 ] ) , abs( a[ k ].p[ 0 ] - s[ cr ].y[ 0 ] ) ) + max( abs( s[ cr ].x[ 1 ] - a[ k ].p[ 1 ] ) , abs( a[ k ].p[ 1 ] - s[ cr ].y[ 1 ] ) ) 。

      (其中0、1表示横坐标、纵坐标,x、y表示最小、最大)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=5e5+5,INF=0x3f3f3f3f;
    int n,rt,ans=INF,fx,tot,mx,mn;
    struct Dt{
        int x[2],y[2],p[2],ly;//x:min y:max p:ps
    }a[N];
    bool cmp(Dt u,Dt v){return u.p[fx]<v.p[fx];}
    struct KD{
        int c[N][2],q;Dt s[N];
        void add(int cr,int k)
        {    for(int i=0;i<=1;i++)
            s[cr].x[i]=s[cr].y[i]=s[cr].p[i]=a[k].p[i], s[cr].ly=k; }
        void pshp(int cr)
        {
            int ls=c[cr][0],rs=c[cr][1];
            for(int i=0;i<=1;i++)
            {
                if(ls) s[cr].x[i]=min(s[cr].x[i],s[ls].x[i]),
                       s[cr].y[i]=max(s[cr].y[i],s[ls].y[i]);
                if(rs) s[cr].x[i]=min(s[cr].x[i],s[rs].x[i]),
                       s[cr].y[i]=max(s[cr].y[i],s[rs].y[i]);
            }
        }
        void build(int &cr,int l,int r,bool now)
        {
            int mid=l+r>>1; fx=now; nth_element(a+l,a+mid,a+r+1,cmp);
            cr=++tot;  add(cr,mid);
            if(l<mid) build(c[cr][0],l,mid-1,!now);
            if(mid<r) build(c[cr][1],mid+1,r,!now);
            pshp(cr);
        }
        int distx(int cr,int k)
        {
            int ret=0;
            for(int i=0;i<=1;i++)
                ret+=max(abs(s[cr].x[i]-a[k].p[i]),abs(a[k].p[i]-s[cr].y[i]));
            return ret;
        }
        int distn(int cr,int k)
        {
            int ret=0;
            for(int i=0;i<=1;i++)
                ret+=max(0,s[cr].x[i]-a[k].p[i])+max(0,a[k].p[i]-s[cr].y[i]);
            return ret;
        }
        int dis(Dt u,Dt v){return abs(u.p[0]-v.p[0])+abs(u.p[1]-v.p[1]);}
        void queryx(int cr,int l,int r)
        {
            mx=max(mx,dis(s[cr],a[q]));
            int ls=c[cr][0], rs=c[cr][1], mid=l+r>>1;
            int dl=(ls?distx(ls,q):-INF), dr=(rs?distx(rs,q):-INF);
            if(dl>dr)
            {    if(dl>mx) queryx(ls,l,mid-1); if(dr>mx) queryx(rs,mid+1,r);}
            else
            {    if(dr>mx) queryx(rs,mid+1,r); if(dl>mx) queryx(ls,l,mid-1);}
        }
        void queryn(int cr,int l,int r)
        {
            if(s[cr].ly!=q) mn=min(mn,dis(s[cr],a[q]));
            int ls=c[cr][0], rs=c[cr][1], mid=l+r>>1;
            int dl=(ls?distn(ls,q):INF), dr=(rs?distn(rs,q):INF);
            if(dl<dr)
            {    if(dl<mn) queryn(ls,l,mid-1); if(dr<mn) queryn(rs,mid+1,r);}
            else
            {    if(dr<mn) queryn(rs,mid+1,r); if(dl<mn) queryn(ls,l,mid-1);}
        }
    }kd;
    int rdn()
    {
        int ret=0; char ch=getchar();
        while(ch>'9'||ch<'0')ch=getchar();
        while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
        return ret;
    }
    int main()
    {
        n=rdn();
        for(int i=1;i<=n;i++)
            a[i].p[0]=rdn(),a[i].p[1]=rdn();
        kd.build(rt,1,n,0);
        for(int i=1,t1,t2;i<=n;i++)
        {
            kd.q=i; mx=-INF; mn=INF; 
            kd.queryx(rt,1,n);  kd.queryn(rt,1,n);
            ans=min(ans,mx-mn);
    //        printf("ans=%d i=%d mx=%d mn=%d
    ",ans,i,mx,mn);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    MySQL优化
    MySQL 的 SQL 操作
    笔记本电脑同时使用两个网络
    top
    logrotate
    正则表达式学习总结
    HttpClient parameter 和body 传输同时进行
    Node.js背景
    前后端分离的理解
    shiro 的subject 以及Context 对象的具体的含义。
  • 原文地址:https://www.cnblogs.com/Narh/p/9598957.html
Copyright © 2011-2022 走看看