您的位置:首页 > 其它

1941: [Sdoi2010]Hide and Seek|K-D Tree

2016-03-11 13:50 447 查看
算是一道裸的kdtree的题了,为什么这么慢QAQ

一遍提交进入最后一页也是种艺术

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define N 500022
using namespace std;
int sc()
{
int i=0,f=1; char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}
struct W{
int d[2],mn[2],mx[2],l,r;
int ans1,ans2;
}t
;
int D,n,m,root,now,ans=1e9;
bool cmp(W a,W b)
{
return a.d[D]<b.d[D];
}
#define L t[x].l
#define R t[x].r
void push_up(int x)
{
for(int i=0;i<=1;i++)
t[x].mn[i]=min(t[x].d[i],min(t[L].mn[i],t[R].mn[i])),
t[x].mx[i]=max(t[x].d[i],max(t[L].mx[i],t[R].mx[i]));
}
void build(int &x,int l,int r,int dir)
{
x=l+r>>1;D=dir;nth_element(t+l,t+x,t+r+1,cmp);
if(l<x)build(L,l,x-1,dir^1);
if(x<r)build(R,x+1,r,dir^1);
push_up(x);
}
int cal(int x,int y)
{
return abs(t[x].d[0]-t[y].d[0])+abs(t[x].d[1]-t[y].d[1]);
}
int c_mx(int x)
{
int ans=0;
for(int i=0;i<=1;i++)
ans+=max(abs(t[x].mn[i]-t[now].d[i]),abs(t[x].mx[i]-t[now].d[i]));
return ans;
}
void query_mx(int x)
{
if(!x)return ;
if(x!=now)
t[now].ans1=max(t[now].ans1,cal(now,x));
int CL=c_mx(L),CR=c_mx(R);
if(CL>CR)
{
if(CL>t[now].ans1)query_mx(L);
if(CR>t[now].ans1)query_mx(R);
}else
{
if(CR>t[now].ans1)query_mx(R);
if(CL>t[now].ans1)query_mx(L);
}
}
bool beset(int x)
{
return t[x].mn[0]<=t[now].d[0] &&
t[x].mx[0]>=t[now].d[0] &&
t[x].mn[1]<=t[now].d[1] &&
t[x].mx[1]>=t[now].d[1];
}
int c_mn(int x)
{
if(beset(x))return 0;
int ans=1e9;
for(int i=0;i<=1;i++)
ans=min(ans,min(abs(t[x].mn[i]-t[now].d[i]),abs(t[x].mx[i]-t[now].d[i])));
return ans;
}
void query_mn(int x)
{
if(!x)return ;
if(x!=now)
t[now].ans2=min(t[now].ans2,cal(now,x));
int CL=c_mn(L),CR=c_mn(R);
if(CL<CR)
{
if(CL<t[now].ans2)query_mn(L);
if(CR<t[now].ans2)query_mn(R);
}else
{
if(CR<t[now].ans2)query_mn(R);
if(CL<t[now].ans2)query_mn(L);
}
}
int main()
{
t[0].mn[0]=t[0].mn[1]=1e9;
t[0].mx[0]=t[0].mx[1]=-1e9;
n=sc();
for(int i=1;i<=n;i++)
t[i].d[0]=sc(),t[i].d[1]=sc();
build(root,1,n,0);
for(int i=1;i<=n;i++)
{
now=i;
t[now].ans1=-1e9;
t[now].ans2=1e9;
query_mx(root);
query_mn(root);
ans=min(ans,t[now].ans1-t[now].ans2);
}
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  K-D-Tree