BZOJ2648:SJY擺棋子
阿新 • • 發佈:2019-02-17
一個個 www use pan res pre space http while
淺談\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html
題目傳送門:https://lydsy.com/JudgeOnline/problem.php?id=2648
\(K-D\) \(Tree\)最近點查詢裸題,註意先把所有點建好再一個個激活。
時間復雜度:\(O(nlogn)\)
空間復雜度:\(O(n)\)
代碼如下:
#include <cstdio> #include <algorithm> using namespace std; const int maxn=5e5+5,inf=2e9; int n,m,pps,ans,node[maxn]; int read() { int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0'; return x*f; } struct query { int opt,x,y; }q[maxn]; struct kd_tree { int cnt,root; int fa[maxn<<1]; struct point { int c[2],mn[2],mx[2],id,ls,rs; point() {} point(int _x,int _y,int _id) { c[0]=_x,c[1]=_y,id=_id; if(id<=n)mn[0]=mx[0]=c[0],mn[1]=mx[1]=c[1]; else mn[0]=mn[1]=inf,mx[0]=mx[1]=-inf; ls=rs=0; } bool operator<(const point &a)const { return c[pps]<a.c[pps]; } }p[maxn<<1]; void update(int u) { int ls=p[u].ls,rs=p[u].rs; for(int i=0;i<2;i++) { int mn=min(p[ls].mn[i],p[rs].mn[i]); p[u].mn[i]=min(p[u].mn[i],mn); int mx=max(p[ls].mx[i],p[rs].mx[i]); p[u].mx[i]=max(p[u].mx[i],mx); } } int build(int l,int r,int cmp) { int mid=(l+r)>>1,u=mid;pps=cmp; nth_element(p+l,p+mid,p+r+1); if(p[u].id>n)node[p[u].id-n]=u; if(l<mid)fa[p[u].ls=build(l,mid-1,cmp^1)]=u; if(r>mid)fa[p[u].rs=build(mid+1,r,cmp^1)]=u; update(u); return u; } void prepare() { p[0]=point(0,0,2e9); for(int i=1;i<=n;i++) { int x=read(),y=read(); p[i]=point(x,y,i); } for(int i=1;i<=m;i++) { int opt=read(),x=read(),y=read(); q[i].opt=opt,q[i].x=x,q[i].y=y; if(opt==1)p[++cnt]=point(x,y,n+i); } root=build(1,cnt,0); } void arouse(int u) { p[u].mn[0]=p[u].mx[0]=p[u].c[0]; p[u].mn[1]=p[u].mx[1]=p[u].c[1]; while(fa[u])update(u),u=fa[u]; update(u); } int dis(int id,int x,int y) { int res=0; if(x<p[id].mn[0])res+=p[id].mn[0]-x; if(x>p[id].mx[0])res+=x-p[id].mx[0]; if(y<p[id].mn[1])res+=p[id].mn[1]-y; if(y>p[id].mx[1])res+=y-p[id].mx[1]; return res; } void query(int u,int x,int y,int id) { if(p[u].id<id)ans=min(ans,abs(x-p[u].c[0])+abs(y-p[u].c[1])); int dl=p[u].ls?dis(p[u].ls,x,y):inf; int dr=p[u].rs?dis(p[u].rs,x,y):inf; if(dl<dr) { if(dl<ans)query(p[u].ls,x,y,id); if(dr<ans)query(p[u].rs,x,y,id); } else { if(dr<ans)query(p[u].rs,x,y,id); if(dl<ans)query(p[u].ls,x,y,id); } } }T; int main() { T.cnt=n=read(),m=read(); T.prepare(); for(int i=1;i<=m;i++) if(q[i].opt==1)T.arouse(node[i]); else { ans=2e9; T.query(T.root,q[i].x,q[i].y,n+i); printf("%d\n",ans); } return 0; }
BZOJ2648:SJY擺棋子