BZOJ 1941: [Sdoi2010]Hide and Seek KDtree + 估价函数

Code:

#include<bits/stdc++.h>
#define maxn 200000
#define inf 1000000000 
using namespace std;
void getmin(int &a,int b) { if(b<a) a=b;  }
void getmax(int &a,int b) { if(b>a) a=b;  }
void setIO(string s)
{
    string in=s+".in"; 
    string out=s+".out"; 
    freopen(in.c_str(),"r",stdin); 
    freopen(out.c_str(),"w",stdout);   
}
namespace KDtree
{
    #define lson t[x].ch[0]
    #define rson t[x].ch[1] 
    #define mid ((l+r)>>1)
    int d,ansmin,ansmax,answer;      
    struct Node
    {
        int ch[2],minv[2],maxv[2],p[2]; 
    }t[maxn],T;   
    bool cmp(Node a,Node b)
    {
        if(a.p[d] == b.p[d]) return a.p[d^1] < b.p[d^1]; 
        return a.p[d] < b.p[d]; 
    }        
    void pushup(int o,int x)
    {
        getmin(t[o].minv[0], t[x].minv[0]); 
        getmax(t[o].maxv[0], t[x].maxv[0]); 
        getmin(t[o].minv[1], t[x].minv[1]); 
        getmax(t[o].maxv[1], t[x].maxv[1]);                           
    }
    int build(int l,int r,int o)
    {
        d=o; 
        nth_element(t+l,t+mid,t+1+r,cmp); 
        t[mid].minv[0]=t[mid].maxv[0]=t[mid].p[0]; 
        t[mid].minv[1]=t[mid].maxv[1]=t[mid].p[1];  
        t[mid].ch[0]=t[mid].ch[1]=0; 
        if(l<mid) 
        {
            t[mid].ch[0]=build(l,mid-1,o^1); 
            pushup(mid,t[mid].ch[0]); 
        }
        if(r>mid) 
        {
            t[mid].ch[1]=build(mid+1,r,o^1); 
            pushup(mid,t[mid].ch[1]);         
        }
        return mid;   
    }
    int _min(Node a)
    {
        int ans=0;                      
        for(int i=0;i<2;++i)
        {
            ans += max(T.p[i]-a.maxv[i], 0); 
            ans += max(a.minv[i]-T.p[i], 0);            
        }
        return ans; 
    }
    int _max(Node a)
    {
        int ans=0; 
        for(int i=0;i<2;++i)
        {
            ans += max(abs(T.p[i]-a.minv[i]), abs(T.p[i]-a.maxv[i])); 
        }
        return ans; 
    }
    void qmin(int x,int x1,int y1)
    {
        int dn=abs(t[x].p[0]-x1) + abs(t[x].p[1]-y1),dl,dr; 
        if(dn>0) getmin(ansmin,dn); 
        dl=lson?_min(t[lson]):inf; 
        dr=rson?_min(t[rson]):inf;   
        if(dl<dr)
        {
            if(dl<ansmin) qmin(lson,x1,y1);        
            if(dr<ansmin) qmin(rson,x1,y1); 
        }
        else
        {
            if(dr<ansmin) qmin(rson,x1,y1); 
            if(dl<ansmin) qmin(lson,x1,y1);        
        }
    }
    void qmax(int x,int x1,int y1)
    {
        int dn=abs(t[x].p[0]-x1) + abs(t[x].p[1]-y1),dl,dr; 
        getmax(ansmax, dn); 
        dl=lson?_max(t[lson]):-inf; 
        dr=rson?_max(t[rson]):-inf; 
        if(dl>dr) 
        {
            if(dl>ansmax) qmax(lson,x1,y1); 
            if(dr>ansmax) qmax(rson,x1,y1); 
        }
        else 
        {
            if(dr>ansmax) qmax(rson,x1,y1); 
            if(dl>ansmax) qmax(lson,x1,y1); 
        }
    }
    void solve(int i,int rt)
    {
        T=t[i], ansmin=inf,ansmax=-inf;   
        qmin(rt, T.p[0], T.p[1]); 
        qmax(rt, T.p[0], T.p[1]); 
        getmin(answer, ansmax-ansmin);              
    }
}; 
int main()
{
    //setIO("A");       
    int n,root,i;
    KDtree::answer=inf; 
    scanf("%d",&n);          
    for(i=1;i<=n;++i) 
        scanf("%d%d",&KDtree::t[i].p[0],&KDtree::t[i].p[1]);  
    root=KDtree::build(1,n,0); 
    for(i=1;i<=n;++i)      
    { 
        KDtree::solve(i,root); 
    }      
    printf("%d\n",KDtree::answer); 
    return 0; 
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值