BZOJ 2648 SJY摆棋子(KD Tree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2648
题意:
思路:
KDtree模板题。
参考自http://www.cnblogs.com/rayrayrainrain/p/6349899.html。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int INF = 0x3f3f3f3f; const int maxn = 300000+5; int x,y; int n,m; int ans; int cmp_d,root; struct node { int d[2],MAX[2],MIN[2]; int l,r; }t[1000005]; bool cmp(node a, node b) { return a.d[cmp_d]<b.d[cmp_d]||a.d[cmp_d]==b.d[cmp_d] && a.d[cmp_d^1] < b.d[cmp_d^1]; } void PushUp(int p,int k) { t[p].MAX[0]=max(t[p].MAX[0],t[k].MAX[0]); t[p].MAX[1]=max(t[p].MAX[1],t[k].MAX[1]); t[p].MIN[0]=min(t[p].MIN[0],t[k].MIN[0]); t[p].MIN[1]=min(t[p].MIN[1],t[k].MIN[1]); } int build(int l,int r, int D) { int mid = (l+r) >> 1; cmp_d = D; nth_element(t+l+1,t+mid+1,t+r+1,cmp) ; t[mid].MAX[0] = t[mid].MIN[0] = t[mid].d[0]; t[mid].MAX[1] = t[mid].MIN[1] = t[mid].d[1]; if(l!=mid) t[mid].l = build(l,mid-1,D^1) ; else t[mid].l = 0; if(r!=mid) t[mid].r = build(mid+1,r,D^1); else t[mid].r = 0; if(t[mid].l) PushUp(mid,t[mid].l); if(t[mid].r) PushUp(mid,t[mid].r); return mid ; } void update(int k) { int p = root ; int D = 0 ; while(true) { PushUp(p,k); if(t[k].d[D] <= t[p].d[D]) { if(!t[p].l) { t[p].l = k ; return; } p = t[p].l ; } else { if(!t[p].r){ t[p].r = k ; return; } p = t[p].r ; } D ^= 1; } } int getdis(int p,int x,int y) { int res = 0; if(x > t[p].MAX[0])res += x - t[p].MAX[0]; if(x < t[p].MIN[0])res += t[p].MIN[0] - x; if(y > t[p].MAX[1])res += y - t[p].MAX[1]; if(y < t[p].MIN[1])res += t[p].MIN[1] - y; return res ; } void query(int p) { int d0 = abs(x - t[p].d[0]) + abs(y - t[p].d[1]) ; if(d0<ans) ans = d0 ; int dl , dr ; if(t[p].l) dl=getdis(t[p].l,x,y) ; else dl = INF ; if(t[p].r) dr=getdis(t[p].r,x,y) ; else dr = INF ; if(dl < dr) { if(dl < ans) query(t[p].l) ; if(dr < ans) query(t[p].r) ; } else { if(dr < ans) query(t[p].r) ; if(dl < ans) query(t[p].l) ; } } int main() { //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); for(int i = 1; i <= n ; i ++ ) scanf("%d%d",&t[i].d[0] , &t[i].d[1]); if(n) root = build(1,n,0) ; for(int i = 1; i <= m ; i ++ ) { int q; scanf("%d%d%d",&q,&x,&y); if(q == 1) { n++ ; t[n].d[0]=t[n].MAX[0]=t[n].MIN[0]=x; t[n].d[1]=t[n].MAX[1]=t[n].MIN[1]=y; if(n>1) update(n); else root = build(1,n,0); } else { ans = INF; query(root); printf("%d\n",ans); } } return 0; }