题目链接:点击这里
解题思路:
对原始的N的点建立KDtree,对于M个操作,黑棋加入新节点,白棋查询最近曼哈顿距离.这就迎刃而解了.
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define fi first
#define se second
using namespace std;
const int mx = 1e6 + 10;
const int mod = 1<<30;
typedef long long ll;
int n,m,now;
int x,y,z,ans;
struct node
{
int mi[2],ma[2];
int l,r,d[2];
bool operator < (node A)const
{
return d[now] < A.d[now];
}
}s[mx];
int dist(node A)
{
return abs(x-A.d[0]) + abs(y-A.d[1]);
}
void update(int rt,int to)
{
for(int i=0;i<2;i++){
s[rt].mi[i] = min(s[rt].mi[i],s[to].mi[i]);
s[rt].ma[i] = max(s[rt].ma[i],s[to].ma[i]);
}
}
int build(int l,int r,int rt)
{
int mid = (l+r)>>1;
now = rt;
nth_element(s+l,s+mid,s+r+1);
for(int i=0;i<2;i++) s[mid].mi[i] = s[mid].ma[i] = s[mid].d[i];
if(l!=mid) s[mid].l = build(l,mid-1,(rt+1)%2);
if(r!=mid) s[mid].r = build(mid+1,r,(rt+1)%2);
if(l!=mid) update(mid,s[mid].l);
if(r!=mid) update(mid,s[mid].r);
return mid;
}
void insert(int rt,int p)
{
now = 0;
while(1){
update(rt,p);
if(s[rt].d[now]>s[p].d[now])
{
if(!s[rt].l){
s[rt].l = p;
return;
}
rt = s[rt].l;
}else{
if(!s[rt].r){
s[rt].r = p;
return ;
}
rt = s[rt].r;
}
now ^= 1;
}
}
int Getdis(int rt)
{
int ret = 0;
if(x<s[rt].mi[0]) ret += s[rt].mi[0] - x;
if(x>s[rt].ma[0]) ret += x - s[rt].ma[0];
if(y<s[rt].mi[1]) ret += s[rt].mi[1] - y;
if(y>s[rt].ma[1]) ret += y - s[rt].ma[1];
return ret;
}
void query(int rt)
{
int dl = inf,dr = inf;
ans = min(ans,dist(s[rt]));
if(s[rt].l) dl = Getdis(s[rt].l);
if(s[rt].r) dr = Getdis(s[rt].r);
if(dl<=dr){
if(dl<ans) query(s[rt].l);
if(dr<ans) query(s[rt].r);
}else{
if(dr<ans) query(s[rt].r);
if(dl<ans) query(s[rt].l);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&s[i].d[0],&s[i].d[1]);
int root = build(1,n,0);
while(m--){
scanf("%d%d%d",&z,&x,&y);
if(z==1){
s[++n].d[0] = x,s[n].d[1] =y;
for(int i=0;i<2;i++) s[n].mi[i] = s[n].ma[i] = s[n].d[i];
insert(root,n);
}else{
ans = inf;
query(root);
printf("%d\n",ans);
}
}
return 0;
}