bzoj 2648: SJY摆棋子(kd tree)

kd tree,裸的模板题。初学,看着别人模板敲了一遍,一直wa,但还找不到原因。。
学习资料:
kd 树算法之思路篇:https://zhuanlan.zhihu.com/p/22557068
kd 树算法之详细篇:https://www.joinquant.com/post/2843
上边两篇和下边这篇还是有那么一点地方不同的。
K-D tree 数据结构:http://blog.csdn.net/zhjchengfeng5/article/details/7855241

代码参考:http://www.cnblogs.com/ljh2000-jump/p/5513620.html

#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1000011;
const int inf = 0x7fffffff;
int n,m;
int nowD;
int root;
int ans;
int ql,qr;

struct node
{
    int Min[2],Max[2];
    int d[2];
    int l,r;
} t[MAXN*2];

int getint()
{
    int w=0,q=0;
    char c=getchar();
    while((c<'0' || c>'9') && c!='-') c=getchar();
    if (c=='-')  q=1, c=getchar();
    while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    return q ? -w : w;
}

bool cmp(node q,node qq)
{
    if(q.d[nowD]==qq.d[nowD]) return q.d[!nowD]<qq.d[!nowD];
    return q.d[nowD]<qq.d[nowD];
}

void kd_updata(int now)
{
    if(t[now].l)
    {
        if(t[t[now].l].Max[0]>t[now].Max[0]) t[now].Max[0]=t[t[now].l].Max[0];
        if(t[t[now].l].Max[1]>t[now].Max[1]) t[now].Max[1]=t[t[now].l].Max[1];
        if(t[t[now].l].Min[0]<t[now].Min[0]) t[now].Min[0]=t[t[now].l].Min[0];
        if(t[t[now].l].Min[1]<t[now].Min[1]) t[now].Min[1]=t[t[now].l].Min[1];
    }
    if(t[now].r)
    {
        if(t[t[now].r].Max[0]>t[now].Max[0]) t[now].Max[0]=t[t[now].r].Max[0];
        if(t[t[now].r].Max[1]>t[now].Max[1]) t[now].Max[1]=t[t[now].r].Max[1];
        if(t[t[now].r].Min[0]<t[now].Min[0]) t[now].Min[0]=t[t[now].r].Min[0];
        if(t[t[now].r].Min[1]<t[now].Min[1]) t[now].Min[1]=t[t[now].r].Min[1];
    }
}

int kd_build(int l,int r,int D)
{
    int mid=(l+r) >> 1;
    nowD=D;
    nth_element(t+l+1,t+mid+1,t+r+1,cmp);

    if(l!=mid)
        t[mid].l=kd_build(l,mid-1,!D);
    if(r!=mid)
        t[mid].r=kd_build(mid+1,r,!D);
    t[mid].Max[0]=t[mid].Min[0]=t[mid].d[0];
    t[mid].Max[1]=t[mid].Min[1]=t[mid].d[1];
    kd_updata(mid);
    return mid;
}

int dist(int p)
{
    int dis=0;
    if(ql < t[p].Min[0])
        dis+=t[p].Min[0]-ql;
    if(ql > t[p].Max[0])
        dis+=ql-t[p].Max[0];
    if(qr < t[p].Min[1])
        dis+=t[p].Min[1]-qr;
    if(qr > t[p].Max[1])
        dis+=qr-t[p].Max[1];
    return dis;
}

void kd_query(int p)
{
    int dl,dr,d0;
    d0=abs(t[p].d[0]-ql)+abs(t[p].d[1]-qr);
    if(d0<ans) ans=d0;

    if(t[p].l) dl=dist(t[p].l);
    else dl=inf;

    if(t[p].r) dr=dist(t[p].r);
    else dr=inf;

    if(dl<dr)
    {
        if(dl<ans) kd_query(t[p].l);
        if(dr<ans) kd_query(t[p].r);
    }
    else
    {
        if(dr<ans) kd_query(t[p].r);
        if(dl<ans) kd_query(t[p].l);
    }
}

inline void kd_insert(int now)
{
    int p=root,D=0;
    while(true)
    {
        if(t[now].Max[0]>t[p].Max[0])
            t[p].Max[0]=t[now].Max[0];
        if(t[now].Max[1]>t[p].Max[1])
            t[p].Max[1]=t[now].Max[1];
        if(t[now].Min[0]<t[p].Min[0])
            t[p].Min[0]=t[now].Min[0];
        if(t[now].Min[1]<t[p].Min[1])
            t[p].Min[1]=t[now].Min[1];

        if(t[now].d[D]>=t[p].d[D])
        {
            if(!t[p].r)
            {
                t[p].r=now;
                return;
            }
            else p=t[p].r;
        }
        else
        {
            if(!t[p].l)
            {
                t[p].l=now;
                return ;
            }
            else p=t[p].l;
        }
        D=!D;
    }
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1; i<=n; i++)
        scanf("%d %d",&t[i].d[0],&t[i].d[1]);
    root=kd_build(1,n,0);

    int x,y,z;
    for(int i=1; i<=m; i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        if(x==1)
        {
            ++n;
            t[n].Max[0]=t[n].Min[0]=t[n].d[0]=y;
            t[n].Max[1]=t[n].Min[1]=t[n].d[1]=z;
            kd_insert(n);
        }
        else
        {
            ans=inf;
            ql=y,qr=z;
            kd_query(root);
            printf("%d\n",ans);
        }
    }
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、下4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、下4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值