K-D tree裸题。对于插入操作可以离线处理,即先把原始的点和所有的即将插入的点一开始全部放在K-D tree里,把一开始没有的点打上标记。在更新答案时,如果没有标记才进行更新。那么添加操作就是单点查找,取消标记。不需要考虑是否有坐标相同的点,因为关注的仅仅是点的坐标。
#include
#include
#include
#define MAXN 1000005
#define Max(x,y) ((x>y)?(x):(y))
#define Min(x,y) ((x
using namespace std;
int N,M;
int D;
struct node{
int d[2],x[2],y[2],son[2];
bool mark;
bool operator<(const node &x)const{return d[D]struct Input{int op,x,y;}qry[MAXN];
void Update(int p,int s)
{
T[p].x[0]=Min(T[p].x[0],T[s].x[0]);
T[p].x[1]=Max(T[p].x[1],T[s].x[1]);
T[p].y[0]=Min(T[p].y[0],T[s].y[0]);
T[p].y[1]=Max(T[p].y[1],T[s].y[1]);
}
int rt,tot;
int Build(int l,int r,int d)
{
D=d;
int p=++tot,mid=l+r>>1;
nth_element(A+l,A+mid,A+r+1);
T[p].d[0]=T[p].x[0]=T[p].x[1]=A[mid].d[0];
T[p].d[1]=T[p].y[0]=T[p].y[1]=A[mid].d[1];
T[p].mark=A[mid].mark;
if(l0]=Build(l,mid-1,d^1),Update(p,T[p].son[0]);
if(r>mid)T[p].son[1]=Build(mid+1,r,d^1),Update(p,T[p].son[1]);
return p;
}
int G(int p,int x,int y)
{
int dx,dy;
dx=Max(0,(T[p].x[0]-x))+Max(0,(x-T[p].x[1]));
dy=Max(0,(T[p].y[0]-y))+Max(0,(y-T[p].y[1]));
return dx+dy;
}
int MinDis;
void GetMin(int p,int x,int y)
{
if(!T[p].mark)MinDis=Min(MinDis,(abs(x-T[p].d[0])+abs(y-T[p].d[1])));
int lg=1e9,rg=1e9;
if(T[p].son[0])lg=G(T[p].son[0],x,y);
if(T[p].son[1])rg=G(T[p].son[1],x,y);
if(lg>=MinDis&&rg>=MinDis)return;
if(lg0],x,y);
if(rg1],x,y);
}
else
{
GetMin(T[p].son[1],x,y);
if(lg0],x,y);
}
}
void Del(int p,int x,int y,int d)//删除标记
{
if(T[p].d[0]==x&&T[p].d[1]==y){T[p].mark=false;return;}
int ls=T[p].son[0],rs=T[p].son[1];
if(!d)
{
if(ls&&T[ls].x[0]<=x&&T[ls].x[1]>=x)Del(ls,x,y,d^1);
if(rs&&T[rs].x[0]<=x&&T[rs].x[1]>=x)Del(rs,x,y,d^1);
}
else
{
if(ls&&T[ls].y[0]<=y&&T[ls].y[1]>=y)Del(ls,x,y,d^1);
if(rs&&T[rs].y[0]<=y&&T[rs].y[1]>=y)Del(rs,x,y,d^1);
}
}
int main()
{
int i,cnt=0;
scanf("%d%d",&N,&M);
for(i=1;i<=N;i++)cnt++,scanf("%d%d",&A[cnt].d[0],&A[cnt].d[1]);
for(i=1;i<=M;i++)
{
scanf("%d%d%d",&qry[i].op,&qry[i].x,&qry[i].y);
if(qry[i].op==1)
{
cnt++;
A[cnt].d[0]=qry[i].x;A[cnt].d[1]=qry[i].y;A[cnt].mark=true;
}
}
rt=Build(1,cnt,0);
for(i=1;i<=M;i++)
{
if(qry[i].op==1)Del(rt,qry[i].x,qry[i].y,0);
else MinDis=1e9,GetMin(rt,qry[i].x,qry[i].y),printf("%d\n",MinDis);
}
}