您的位置:首页 > 其它

[bzoj1941]k-d tree 模板

2017-10-31 07:18 274 查看
w_yqts 的指导下学习了kdtree……

http://blog.csdn.net/silangquan/article/details/41483689

听说这东西很优秀……Orz

但看起来就像一个暴力剪枝.

#include <cstdio>
#include <algorithm>
using namespace std;
#define inf 1000000000
#define N 500005
#define K 2
inline int read()
{
char ch=getchar();
int x=0,f=1;
while ('0'>ch || ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while ('0'<=ch && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
int kd,rt,nx,mx;
int n,ans;
struct node
{
int l,r,n[K],m[K];
}tr
;
struct KD
{
int k[K];
}a
;
inline int dis(const KD x,const KD y)
{
int res=0;
for (int i=0;i<K;++i) res+=abs(x.k[i]-y.k[i]);
return res;
}
bool cmp(KD x,KD y)
{
return x.k[kd]<y.k[kd];
}
inline void update(int x)
{
int l=tr[x].l,r=tr[x].r;
for (int i=0;i<K;++i)
{
tr[x].n[i]=tr[x].m[i]=a[x].k[i];
if (l) tr[x].n[i]=min(tr[x].n[i],tr[l].n[i]);
if (r) tr[x].n[i]=min(tr[x].n[i],tr[r].n[i]);
if (l) tr[x].m[i]=max(tr[x].m[i],tr[l].m[i]);
if (r) tr[x].m[i]=max(tr[x].m[i],tr[r].m[i]);
}
}
int build(int l,int r)
{
if (l>r) return 0;
int mid=(l+r)>>1;
nth_element(a+l,a+mid,a+1+r,cmp);
for (int i=0;i<K;++i) tr[mid].n[i]=tr[mid].m[i]=a[mid].k[i];
if (l==r) return l;
kd^=1;
tr[mid].l=build(l,mid-1);
tr[mid].r=build(mid+1,r);
kd^=1;
update(mid);
return mid;
}
inline int getnx(int x,const KD t)
{
int dis=0;
for (int i=0;i<K;++i)
dis+=max(t.k[i]-tr[x].m[i],0)+max(tr[x].n[i]-t.k[i],0);
return dis;
}
inline int getmx(int x,const KD t)
{
int dis=0;
for (int i=0;i<K;++i) dis+=max(abs(t.k[i]-tr[x].n[i]),abs(t.k[i]-tr[x].m[i]));
return dis;
}
void querynx(int x,const KD t)
{
int tmp=dis(a[x],t);
if (tmp) nx=min(nx,tmp);
int l=tr[x].l,r=tr[x].r,disl=inf,disr=inf;
if (l) disl=getnx(l,t);
if (r) disr=getnx(r,t);
if (disl<disr)
{
if (disl<nx) querynx(l,t);
if (disr<nx) querynx(r,t);
}else
{
if (disr<nx) querynx(r,t);
if (disl<nx) querynx(l,t);
}
}
void querymx(int x,const KD t)
{
int tmp=dis(a[x],t);
mx=max(mx,tmp);
int l=tr[x].l,r=tr[x].r,disl=-inf,disr=-inf;
if (l) disl=getmx(l,t);
if (r) disr=getmx(r,t);
if (disl>disr)
{
if (disl>mx) querymx(l,t);
if (disr>mx) querymx(r,t);
}else
{
if (disr>mx) querymx(r,t);
if (disl>mx) querymx(l,t);
}
}
inline void solve(const KD x)
{
nx=inf,mx=-inf;
querynx(rt,x);
querymx(rt,x);
ans=min(ans,mx-nx);
}
int main()
{
n=read();
for (int i=1;i<=n;++i) for (int k=0;k<K;++k) a[i].k[k]=read();
rt=build(1,n);
ans=inf;
for (int i=1;i<=n;++i) solve(a[i]);
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: