码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2648 SJY摆棋子——KDtree

时间:2018-08-16 22:31:37      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:printf   oid   pac   string   inf   class   for   pre   代码   

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648

第一道KDtree!

学习资料:https://blog.csdn.net/zhl30041839/article/details/9277807

     https://www.cnblogs.com/galaxies/p/kdtree.html

这道题的代码是学习(抄)的这里的:https://blog.csdn.net/lych_cys/article/details/50809141

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+5,INF=0x3f3f3f3f;
int n,m,fx,rt,ans,tot;
struct Node{
    int x[2],y[2],p[2];//x:min y:max p:ps
}a[N>>1];
bool cmp(Node u,Node v){return u.p[fx]<v.p[fx];}
struct Kd{
    int c[N][2];Node s[N],q;//大家的儿子、根和唯一的询问
    void add(int cr,Node k)
    {    for(int i=0;i<2;i++) s[cr].x[i]=s[cr].y[i]=s[cr].p[i]=k.p[i];}
    void pshp(int cr)
    {
        int ls=c[cr][0],rs=c[cr][1];
        for(int i=0;i<2;i++)
        {
            if(ls)
                s[cr].x[i]=min(s[cr].x[i],s[ls].x[i]),
                s[cr].y[i]=max(s[cr].y[i],s[ls].y[i]);
            if(rs)
                s[cr].x[i]=min(s[cr].x[i],s[rs].x[i]),
                s[cr].y[i]=max(s[cr].y[i],s[rs].y[i]);
        }
    }
    void build(int &cr,int l,int r,int now)
    {
        int mid=l+r>>1;fx=now;
        nth_element(a+l,a+mid,a+r+1,cmp);
//        cr=mid;add(cr,a[mid]);//////cr=mid!
        cr=++tot;add(cr,a[mid]);
        if(l<mid)build(c[cr][0],l,mid-1,!now);///if()
        if(mid<r)build(c[cr][1],mid+1,r,!now);
        pshp(cr);
    }
    void insert(int &cr,int now)
    {
//        if(!cr){cr=++n;add(cr,q);return;}//cr=++n!
        if(!cr){cr=++tot;add(cr,q);return;}
        if(q.p[now]<s[cr].p[now])insert(c[cr][0],!now);
        else insert(c[cr][1],!now);
        pshp(cr);
    }
    int dist(int cr,Node k)//在区域内返回0 
    {
        int ret=0;
        for(int i=0;i<2;i++)
            ret+=max(0,s[cr].x[i]-k.p[i])+max(0,k.p[i]-s[cr].y[i]);
        return ret;
    }
    void query(int cr,int now)
    {
        ans=min(ans,abs(s[cr].p[0]-q.p[0])+abs(s[cr].p[1]-q.p[1]));
        int dl=c[cr][0]?dist(c[cr][0],q):INF,dr=c[cr][1]?dist(c[cr][1],q):INF;
        if(dl<dr)
        { if(dl<ans)query(c[cr][0],!now); if(dr<ans)query(c[cr][1],!now);}
        else
        { if(dr<ans)query(c[cr][1],!now); if(dl<ans)query(c[cr][0],!now);}
    }
}kd;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d%d",&a[i].p[0],&a[i].p[1]);
    kd.build(rt,1,n,0);
    for(int i=1,op;i<=m;i++)
    {
        scanf("%d%d%d",&op,&kd.q.p[0],&kd.q.p[1]);
        if(op==1) kd.insert(rt,0);
        else {    ans=INF; kd.query(rt,0); printf("%d\n",ans);}
    }
    return 0;
}

 

bzoj 2648 SJY摆棋子——KDtree

标签:printf   oid   pac   string   inf   class   for   pre   代码   

原文地址:https://www.cnblogs.com/Narh/p/9490321.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!