不得不承認KDtree的卻是二維空間類距離處理利器,省去了樹套樹繁瑣的操作,code簡潔明瞭。
爲了防止KDtree我還特意加上了rebuild的操作……結果反而更滿了……,cnt太小<=70000還會TLE……WCO
哎,KDTREE就那樣吧,隨便打打,開心開心就好了。
//去掉rebuild操作更快。
#include<bits/stdc++.h>
inline int maxn(int x,int y){return x<y?y:x;}
inline int minn(int x,int y){return x<y?x:y;}
int n,m,root,cmp_d,k1,k2,k3,ans;
struct node{
int d[2],l,r,maxn[2],minn[2];
}tree[1000001],pte[1000001],tmp;
inline bool cmp(node a,node b){
return (a.d[cmp_d]<b.d[cmp_d])||
((a.d[cmp_d]==b.d[cmp_d])&&(a.d[!cmp_d]<b.d[!cmp_d]));
}
void update(const int p){
if(tree[p].l){
if(tree[p].maxn[0]<tree[tree[p].l].maxn[0])tree[p].maxn[0]=tree[tree[p].l].maxn[0];
if(tree[p].minn[0]>tree[tree[p].l].minn[0])tree[p].minn[0]=tree[tree[p].l].minn[0];
if(tree[p].maxn[1]<tree[tree[p].l].maxn[1])tree[p].maxn[1]=tree[tree[p].l].maxn[1];
if(tree[p].minn[1]>tree[tree[p].l].minn[1])tree[p].minn[1]=tree[tree[p].l].minn[1];
}if(tree[p].r){
if(tree[p].maxn[0]<tree[tree[p].r].maxn[0])tree[p].maxn[0]=tree[tree[p].r].maxn[0];
if(tree[p].minn[0]>tree[tree[p].r].minn[0])tree[p].minn[0]=tree[tree[p].r].minn[0];
if(tree[p].maxn[1]<tree[tree[p].r].maxn[1])tree[p].maxn[1]=tree[tree[p].r].maxn[1];
if(tree[p].minn[1]>tree[tree[p].r].minn[1])tree[p].minn[1]=tree[tree[p].r].minn[1];
}
}
int build(const int l,const int r,const int D){
if(l>r)return 0;
register int mid=(l+r)>>1;
cmp_d=D;std::nth_element(pte+l+1,pte+mid+1,pte+r+1,cmp);
tree[mid]=pte[mid];
tree[mid].maxn[0]=tree[mid].minn[0]=tree[mid].d[0];
tree[mid].maxn[1]=tree[mid].minn[1]=tree[mid].d[1];
tree[mid].l=build(l,mid-1,!D);
tree[mid].r=build(mid+1,r,!D);
update(mid);
return mid;
}
inline void insert(const int now){
register int D,p;
D=0;p=root;
while(1){
if(tree[now].maxn[0]>tree[p].maxn[0])tree[p].maxn[0]=tree[now].maxn[0];
if(tree[now].maxn[1]>tree[p].maxn[1])tree[p].maxn[1]=tree[now].maxn[1];
if(tree[now].minn[0]<tree[p].minn[0])tree[p].minn[0]=tree[now].minn[0];
if(tree[now].minn[1]<tree[p].minn[1])tree[p].minn[1]=tree[now].minn[1];
if(tree[now].d[D]>=tree[p].d[D]){
if(tree[p].r==0){
tree[p].r=now;
return;
}else p=tree[p].r;
}else{
if(tree[p].l==0){
tree[p].l=now;
return;
}else p=tree[p].l;
}
D=!D;
}
}
inline int dist(const int p1,const int px,const int py){
register int dis=0;
if(px<tree[p1].minn[0])dis+=tree[p1].minn[0]-px;
if(px>tree[p1].maxn[0])dis+=px-tree[p1].maxn[0];
if(py<tree[p1].minn[1])dis+=tree[p1].minn[1]-py;
if(py>tree[p1].maxn[1])dis+=py-tree[p1].maxn[1];
return dis;
}
inline void query(const int p){
register int dl,dr,d0;
d0=abs(tree[p].d[0]-k2)+abs(tree[p].d[1]-k3);
if(d0<ans)ans=d0;
if(tree[p].l)dl=dist(tree[p].l,k2,k3);else dl=0x7f7f7f7f;
if(tree[p].r)dr=dist(tree[p].r,k2,k3);else dr=0x7f7f7f7f;
if(dl<dr){
if(dl<ans)query(tree[p].l);
if(dr<ans)query(tree[p].r);
}else{
if(dr<ans)query(tree[p].r);
if(dl<ans)query(tree[p].l);
}
}
template<class T>inline void read(T &res){
static char ch;T flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int main(){
read(n),read(m);
register int i,j,cnt=0;
tree[0].maxn[0]=tree[0].maxn[1]=-0x7f7f7f7f;
tree[0].minn[0]=tree[0].minn[1]= 0x7f7f7f7f;
for(i=1;i<=n;++i)read(pte[i].d[0]),read(pte[i].d[1]);
root=build(1,n,0);
for(i=1;i<=m;++i){
read(k1),read(k2),read(k3);
if(k1==1){
++n;
tree[n].maxn[0]=tree[n].minn[0]=tree[n].d[0]=k2;
tree[n].maxn[1]=tree[n].minn[1]=tree[n].d[1]=k3;
insert(n);
if(++cnt==200000){
for(j=1;j<=n;j++)pte[j]=tree[j];
root=build(1,n,0);cnt=0;
}
}else{
ans=0x7f7f7f7f;
query(root);
printf("%d\n",ans);
}
}
return 0;
}