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; }