# 【bzoj2648】SJY摆棋子 KD-tree

2 3
1 1
2 3
2 1 2
1 3 3
2 4 2

1
2

KD-tree模板题

#include <cstdio>
#include <algorithm>
#define N 1000010
#define inf 0x7fffffff
using namespace std;
struct data
{
int p[2] , maxn[2] , minn[2] , c[2];
}a[N];
int root , d , ans;
bool cmp(data a , data b)
{
return a.p[d] == b.p[d] ? a.p[d ^ 1] < b.p[d ^ 1] : a.p[d] < b.p[d];
}
void pushup(int k , int s)
{
a[k].maxn[0] = max(a[k].maxn[0] , a[s].maxn[0]);
a[k].maxn[1] = max(a[k].maxn[1] , a[s].maxn[1]);
a[k].minn[0] = min(a[k].minn[0] , a[s].minn[0]);
a[k].minn[1] = min(a[k].minn[1] , a[s].minn[1]);
}
int build(int l , int r , int now)
{
int mid = (l + r) >> 1;
d = now , nth_element(a + l , a + mid , a + r + 1 , cmp);
a[mid].maxn[0] = a[mid].minn[0] = a[mid].p[0];
a[mid].maxn[1] = a[mid].minn[1] = a[mid].p[1];
if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1) , pushup(mid , a[mid].c[0]);
if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1) , pushup(mid , a[mid].c[1]);
return mid;
}
void ins(int k)
{
int *t = &root;
d = 0;
while(*t) pushup(*t , k) , t = &a[*t].c[a[k].p[d] > a[*t].p[d]] , d ^= 1;
*t = k;
}
int getdis(int k , int x , int y)
{
int ans = 0;
if(x < a[k].minn[0]) ans += a[k].minn[0] - x;
if(x > a[k].maxn[0]) ans += x - a[k].maxn[0];
if(y < a[k].minn[1]) ans += a[k].minn[1] - y;
if(y > a[k].maxn[1]) ans += y - a[k].maxn[1];
return ans;
}
void query(int k , int x , int y)
{
int dn = abs(x - a[k].p[0]) + abs(y - a[k].p[1]) , dl , dr;
if(dn < ans) ans = dn;
dl = a[k].c[0] ? getdis(a[k].c[0] , x , y) : inf;
dr = a[k].c[1] ? getdis(a[k].c[1] , x , y) : inf;
if(dl < dr)
{
if(dl < ans) query(a[k].c[0] , x , y);
if(dr < ans) query(a[k].c[1] , x , y);
}
else
{
if(dr < ans) query(a[k].c[1] , x , y);
if(dl < ans) query(a[k].c[0] , x , y);
}
}
int main()
{
int n , m , i , opt , x , y;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &a[i].p[0] , &a[i].p[1]);
root = build(1 , n , 0);
while(m -- )
{
scanf("%d%d%d" , &opt , &x , &y);
if(opt == 1) n ++ , a[n].p[0] = a[n].maxn[0] = a[n].minn[0] = x , a[n].p[1] = a[n].maxn[1] = a[n].minn[1] = y , ins(n);
else ans = inf , query(root , x , y) , printf("%d\n" , ans);
}
return 0;
}


|转载请注明 [原文链接][作者] ，谢谢！

posted @ 2017-06-02 16:55  GXZlegend  阅读(287)  评论(0编辑  收藏  举报