您的位置:首页 > 其它

k-d树模板(BZOJ2648)

2016-12-22 09:46 267 查看
实现了插入一个点,查询距某个位置的最近点。

#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 500005, inf = 0x3f3f3f3f;
int n,q,D,rt,op,ans,b[2];
struct nd {
int l,r,d[2],mn[2],mx[2];
bool operator < (const nd &b) const {return d[D] < b.d[D];}
}t[N<<1];
int rd() {
int r = 0, f = 1, c = getchar();
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') r = r*10+c-'0', c = getchar();
return r*f;
}

void pu(int x) {
for(int i = 0; i < 2; i++) {
t[x].mn[i] = min(t[x].mn[i],min(t[t[x].l].mn[i],t[t[x].r].mn[i]));
t[x].mx[i] = max(t[x].mx[i],max(t[t[x].l].mx[i],t[t[x].r].mx[i]));
}
}
int bd(int l, int r, int d) {
if(l > r) return 0;
int m = (l+r)>>1;
D = d, nth_element(t+l, t+m, t+r+1);
for(int i = 0; i < 2; i++) t[m].mn[i] = t[m].mx[i] = t[m].d[i];
t[m].l = bd(l, m-1, d^1), t[m].r = bd(m+1, r, d^1), pu(m);
return m;
}
void in(int o, int d) {
if(b[d] >= t[o].d[d]) {
if(t[o].r) in(t[o].r, d^1);
else {
t[o].r = ++n;
for(int i = 0; i < 2; i++) t
.mn[i] = t
.mx[i] = t
.d[i] = b[i];
}
} else {
if(t[o].l) in(t[o].l, d^1);
else {
t[o].l = ++n;
for(int i = 0; i < 2; i++) t
.mn[i] = t
.mx[i] = t
.d[i] = b[i];
}
}
pu(o);
}
int gt(int o, int x, int y) {
return max(0,t[o].mn[0]-x)+max(0,t[o].mn[1]-y)+max(0,x-t[o].mx[0])+max(0,y-t[o].mx[1]);
}
void qry(int o, int x, int y) {
int ds = abs(t[o].d[0]-x)+abs(t[o].d[1]-y), dl = gt(t[o].l,x,y), dr = gt(t[o].r,x,y);
ans = min(ans, ds);
if(!t[o].l) dl = inf; if(!t[o].r) dr = inf;
if(dl < dr) {
if(dl < ans) qry(t[o].l,x,y);
if(dr < ans) qry(t[o].r,x,y);
} else {
if(dr < ans) qry(t[o].r,x,y);
if(dl < ans) qry(t[o].l,x,y);
}
}

int main() {
n = rd(), q = rd();
for(int i = 1; i <= n; i++) t[i].d[0] = rd(), t[i].d[1] = rd();
t[0].mn[0] = t[0].mn[1] = inf, t[0].mx[0] = t[0].mx[1] = -inf, rt = bd(1, n, 0);
while(q--) {
op = rd(), b[0] = rd(), b[1] = rd();
if(op^1) ans = inf, qry(rt,b[0],b[1]), printf("%d\n", ans); else in(rt,0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: