首页 > 代码库 > POJ 3470 Walls(线段树+扫描线)
POJ 3470 Walls(线段树+扫描线)
【题目链接】 http://poj.org/problem?id=3470
【题目大意】
给出几面墙,均垂直于x轴或者y轴,给出一些鸟的位置(二维坐标点),
鸟只会垂直x轴或者y轴飞行,并且会撞上最近的墙,问每面墙最后会有几只鸟撞上去。
【题解】
我们将所有的二维坐标离散,对xy方向分别进行扫描线,
以y轴方向为例,我们先从y最小的线开始扫,
如果是墙,那么在线段树中更新其在x轴上的分布位置
如果是鸟的坐标,那么在线段树中查找其位置,更新其答案。
之后从y最大的开始反向扫描,更新,x方向也同理。
【代码】
#include <cstdio>#include <algorithm> #include <cstring>#include <climits>using namespace std;const int N=50010;int n,m,wall,tot,dis[N],v[N],w[N],T[10*N],*arr;int x[3*N],y[3*N],ry[3*N],rx[3*N],r[3*N],xs[3*N],ys[3*N],px[3*N],py[3*N];bool cmp(int a,int b){return arr[a]<arr[b];}void compress(int *x,int *r,int n,int *a,int *mp){ for(int i=0;i<n;i++)r[i]=i; arr=x; sort(r,r+n,cmp); int m=-1; a[r[0]]=++m; mp[m]=x[r[0]]; for(int i=1;i<n;i++){ int cur=r[i],lst=r[i-1]; if(x[cur]==x[lst])a[cur]=m; else a[cur]=++m,mp[m]=x[cur]; }}int query(int q,int x,int l,int r){ if(T[x]!=-2)return T[x]; int mid=(l+r)>>1; if(q<mid)return query(q,x<<1|1,l,mid); return query(q,x+1<<1,mid,r);}void update(int a,int b,int x,int l,int r,int val){ if(r<=a||b<=l)return; else if(a<=l&&r<=b)T[x]=val; else{ if(T[x]!=-2){ T[x+1<<1]=T[x<<1|1]=T[x]; T[x]=-2; }int mid=(l+r)>>1; update(a,b,x<<1|1,l,mid,val); update(a,b,x+1<<1,mid,r,val); }}void scan(int k,int *ys,int *xs,int *py,int W){ if(k<wall){ int _k=k^1; if(xs[_k]>=xs[k])update(xs[k],xs[_k]+1,0,0,W,k/2); }else{ int t=query(xs[k],0,0,W); if(~t){ int d=min(abs(py[ys[k]]-py[ys[t*2]]),abs(py[ys[k]]-py[ys[t*2+1]])); k-=wall; if(d<dis[k])dis[k]=d,v[k]=t; } }}void fly(int *ry,int *ys,int *xs,int *py,int W){ T[0]=-1; for(int i=0;i<tot;i++)scan(ry[i],ys,xs,py,W); T[0]=-1; for(int i=tot-1;i>=0;i--)scan(ry[i],ys,xs,py,W); }int main(){ scanf("%d%d",&n,&m); wall=2*n; tot=wall+m; for(int i=0;i<tot;i++)scanf("%d%d",x+i,y+i); compress(x,rx,tot,xs,px); compress(y,ry,tot,ys,py); fill(dis,dis+m,INT_MAX);memset(w,0,n); fly(ry,ys,xs,py,xs[rx[tot-1]]+1); fly(rx,xs,ys,px,ys[ry[tot-1]]+1); for(int i=0;i<m;i++)++w[v[i]]; for(int i=0;i<n;i++)printf("%d\n",w[i]); return 0;}
POJ 3470 Walls(线段树+扫描线)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。