k-d树模板(BZOJ2648)

实现了插入一个点,查询距某个位置的最近点。

#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[n].mn[i] = t[n].mx[i] = t[n].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[n].mn[i] = t[n].mx[i] = t[n].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;
}
posted @ 2016-12-22 09:46  Monster_Yi  阅读(205)  评论(0编辑  收藏  举报