k-d tree模板练习

Posted ditoly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k-d tree模板练习相关的知识,希望对你有一定的参考价值。

1. [BZOJ]1941: [Sdoi2010]Hide and Seek

题目大意:给出n个二维平面上的点,一个点的权值是它到其他点的最长距离减最短距离,距离为曼哈顿距离,求最小权值。(n<=500,000)

思路:k-d tree裸题。

#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
    int x;char c;
    while((c=getchar())<0||c>9);
    for(x=c-0;(c=getchar())>=0&&c<=9;)x=(x<<3)+(x<<1)+c-0;
    return x;
}
#define MN 500000
#define INF 0x7FFFFFFF
int rt,D,q[2];
struct node
{
    int p[2],mn[2],mx[2],l,r;
    friend bool operator<(const node&a,const node&b){return a.p[D]<b.p[D];}
}t[MN+5];
void up(int k)
{
    for(int l=t[k].l,r=t[k].r,i=0;i<2;++i)
        t[k].mn[i]=t[k].mx[i]=t[k].p[i],
        l?(t[k].mn[i]=min(t[k].mn[i],t[l].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[l].mx[i])):0,
        r?(t[k].mn[i]=min(t[k].mn[i],t[r].mn[i]),t[k].mx[i]=max(t[k].mx[i],t[r].mx[i])):0;
}
int build(int l,int r)
{
    if(l>r)return 0;
    int mid=l+r>>1;
    nth_element(t+l,t+mid,t+r+1);
    D^=1;t[mid].l=build(l,mid-1);D^=1;
    D^=1;t[mid].r=build(mid+1,r);D^=1;
    return up(mid),mid;
}
inline int calmx(int k)
{
    return max(abs(q[0]-t[k].mn[0]),abs(t[k].mx[0]-q[0]))+
           max(abs(q[1]-t[k].mn[1]),abs(t[k].mx[1]-q[1]));
}
void qmx(int k)
{
    D=max(D,abs(t[k].p[0]-q[0])+abs(t[k].p[1]-q[1]));
    int dl=t[k].l?calmx(t[k].l):-INF,dr=t[k].r?calmx(t[k].r):-INF;
    if(dl>dr){if(dl>D)qmx(t[k].l);if(dr>D)qmx(t[k].r);}
         else{if(dr>D)qmx(t[k].r);if(dl>D)qmx(t[k].l);}
}
inline int calmn(int k)
{
    return max(t[k].mn[0]-q[0],0)+max(q[0]-t[k].mx[0],0)+
           max(t[k].mn[1]-q[1],0)+max(q[1]-t[k].mx[1],0);
}
void qmn(int k)
{
    int x=abs(t[k].p[0]-q[0])+abs(t[k].p[1]-q[1]);if(x)D=min(D,x);
    int dl=t[k].l?calmn(t[k].l):INF,dr=t[k].r?calmn(t[k].r):INF;
    if(dl<dr){if(dl<D)qmn(t[k].l);if(dr<D)qmn(t[k].r);}
         else{if(dr<D)qmn(t[k].r);if(dl<D)qmn(t[k].l);}
}
int main()
{
    int n=read(),i,x,ans=INF;
    for(i=1;i<=n;++i)t[i].p[0]=read(),t[i].p[1]=read();
    rt=build(1,n);
    for(i=1;i<=n;++i)
    {
        q[0]=t[i].p[0];q[1]=t[i].p[1];
        D=-INF;qmx(rt);x=D;
        D=INF;qmn(rt);
        ans=min(ans,x-D);
    }
    printf("%d",ans);
}

 

以上是关于k-d tree模板练习的主要内容,如果未能解决你的问题,请参考以下文章

浅谈K-D Tree

k-d tree

K-D Tree

简单题(K-D Tree)

k-d tree学习总结

BZOJ 2648: SJY摆棋子(K-D Tree)