bzoj 2648 SJY摆棋子——KDtree

时间:2025-03-24 12:05:55

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

第一道KDtree!

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

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

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

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