双倍经验QAQ
kd树裸题,估价函数千万不要自己乱YY
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define N 1000022
using namespace std;
int sc()
{
int i=0,f=1; char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}
struct W{
int d[2],mn[2],mx[2],l,r;
}t[N],now;
int n,m,cnt,root,D,ans;
bool cmp(W a,W b)
{
return a.d[D]<b.d[D];
}
#define L t[x].l
#define R t[x].r
void push_up(int x)
{
for(int i=0;i<=1;i++)
t[x].mx[i]=max(t[x].d[i],max(t[L].mx[i],t[R].mx[i])),
t[x].mn[i]=min(t[x].d[i],min(t[L].mn[i],t[R].mn[i]));
}
void build(int &x,int l,int r,int dir)
{
D=dir;x=l+r>>1;
nth_element(t+l,t+x,t+r+1,cmp);
if(l<x)build(L,l,x-1,dir^1);
if(x<r)build(R,x+1,r,dir^1);
push_up(x);
}
void insert(int &x,int d)
{
if(!x)
x=++cnt,
t[x]=now;
else if(now.d[d]<t[x].d[d]) insert(L,d^1);
else insert(R,d^1);
push_up(x);
}
int dis(int x,W y)
{
return abs(t[x].d[0]-y.d[0])+abs(t[x].d[1]-y.d[1]);
}
int cal(int x)
{
return max(t[x].mn[0]-now.d[0],0)+max(now.d[0]-t[x].mx[0],0)+
max(t[x].mn[1]-now.d[1],0)+max(now.d[1]-t[x].mx[1],0);
}
void query(int x)
{
if(!x)return;
ans=min(ans,dis(x,now));
int cl=1e9,cr=1e9;
if(L)cl=cal(L);if(R)cr=cal(R);
if(cl<cr)
{
if(cl<ans)query(L);
if(cr<ans)query(R);
}else
{
if(cr<ans)query(R);
if(cl<ans)query(L);
}
}
int main()
{
t[0].mn[0]=t[0].mn[1]=1e9;
t[0].mx[0]=t[0].mx[1]=-1e9;
cnt=n=sc(),m=sc();
for(int i=1;i<=n;i++)
t[i].d[0]=sc(),t[i].d[1]=sc();
build(root,1,n,0);
while(m--)
{
int t=sc();
now.d[0]=sc();
now.d[1]=sc();
if(t==1)
insert(root,0);
else
{
ans=1e9;
query(root);
printf("%d\n",ans);
}
}
return 0;
}