题意
这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
分析
K-DTree模板题,当作复习
每次记录子树内最大最小值,看看距离询问点至少有多远,来写估价函数
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
inline int read()
{
int p=0; int f=1; char ch = getchar();
while(ch<'0' || ch>'9'){if(ch == '-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
struct node
{
int son[2] , mn[2] , mx[2] , d[2];
}tr[N]; int rt,tot;
int D;
bool cmp(const node &x,const node &y)
{
if(x.d[D] != y.d[D]) return x.d[D] < y.d[D];
return x.d[D^1] < y.d[D^1];
}
void upd(int x,int y)
{
for(int i=0;i<2;i++)
{
tr[x].mn[i] = min(tr[x].mn[i],tr[y].mn[i]);
tr[x].mx[i] = max(tr[x].mx[i],tr[y].mx[i]);
}
}
int build(int dem,int L,int R)
{
D = dem; int mid=(L+R)>>1; nth_element(tr+L,tr+mid,tr+R+1,cmp);
tr[mid].mn[0] = tr[mid].mx[0] = tr[mid].d[0];
tr[mid].mn[1] = tr[mid].mx[1] = tr[mid].d[1];
if(L<mid) tr[mid].son[0] = build(dem^1,L,mid-1),upd(mid,tr[mid].son[0]);
if(mid<R) tr[mid].son[1] = build(dem^1,mid+1,R),upd(mid,tr[mid].son[1]);
return mid;
}
void insert(int x)
{
int u = rt; D = 1;
while(u)
{
upd(u,x);
if(tr[x].d[D] <= tr[u].d[D])
{
if(tr[u].son[0]) u=tr[u].son[0];
else{tr[u].son[0] = x; return ;}
}
else
{
if(tr[u].son[1]) u=tr[u].son[1];
else{tr[u].son[1] = x; return ;}
}
D^=1;
}
}
int ans = INT_MAX;
int calc(int u,int x,int y)
{
int s = 0;
if(tr[u].mx[0] < x) s += x - tr[u].mx[0];
if(tr[u].mx[1] < y) s += y - tr[u].mx[1];
if(tr[u].mn[0] > x) s += tr[u].mn[0] - x;
if(tr[u].mn[1] > y) s += tr[u].mn[1] - y;
return s;
}
void qry(int u,int x,int y)
{
if(!u) return ;
ans = min(ans , abs(x - tr[u].d[0]) + abs(y - tr[u].d[1]));
int d0 = INT_MAX,d1 = INT_MAX;
if(tr[u].son[0]) d0 = calc(tr[u].son[0],x,y); if(tr[u].son[1]) d1 = calc(tr[u].son[1],x,y);
if(d0 < d1)
{
if(d0 < ans) qry(tr[u].son[0],x,y);
if(d1 < ans) qry(tr[u].son[1],x,y);
}
else
{
if(d1 < ans) qry(tr[u].son[1],x,y);
if(d0 < ans) qry(tr[u].son[0],x,y);
}
}
int main()
{
int n = read(); int m = read();
for(int i=1;i<=n;i++) tr[i].d[0] = read(), tr[i].d[1] = read();
rt = build(1,1,n);
for(int i=1;i<=m;i++)
{
int op = read();
if(op==1)
{
n++; tr[n].d[0] = tr[n].mx[0] = tr[n].mn[0] = read(); tr[n].d[1] = tr[n].mx[1] = tr[n].mn[1] = read();
insert(n);
}
else
{
int x = read(); int y = read(); ans=INT_MAX;
qry(rt,x,y);
printf("%d\n",ans);
}
}
return 0;
}