POJ 2482 Stars in Your Window(扫描线+线段树)
【题目链接】 http://poj.org/problem?id=2482
【题目大意】
给出一些点的二维坐标和权值,求用一个长H,宽W的矩形能框住的最大权值之和,
在矩形边缘的点不计算在内
【题解】
我们计算能扫到这个点的区间范围,将其拆分为两条平行于y轴的左闭右开的直线,
为方便边界处理,我们将坐标扩大两倍,之后我们按照x轴对这些线段进行扫描
统计出现的最大值即可。
【代码】
#include <cstdio> #include <algorithm> #include <utility> using namespace std; typedef long long LL; const int N=10010; LL xs[N],ys[N],X[N<<1],Y[N<<1]; int cs[N],tag[N<<3],T[N<<3]; pair<pair<int,int>,pair<int,int> >event[N<<1]; void update(int L,int R,int v,int x,int l,int r){ if(L<=l&&r<=R){T[x]+=v;tag[x]+=v;return;} int mid=(l+r)>>1; if(L<=mid)update(L,R,v,x<<1,l,mid); if(mid<R)update(L,R,v,x<<1|1,mid+1,r); T[x]=max(T[x<<1],T[x<<1|1])+tag[x]; } int n,W,H; void solve(){ for(int i=0;i<n;i++){ scanf("%lld%lld%d",xs+i,ys+i,cs+i); xs[i]<<=1; ys[i]<<=1; } for(int i=0;i<n;i++){ X[i<<1]=xs[i]-W; X[i<<1|1]=xs[i]+W; Y[i<<1]=ys[i]-H; Y[i<<1|1]=ys[i]-1+H; }sort(X,X+n*2);sort(Y,Y+n*2); for(int i=0;i<n;i++){ event[i<<1]=make_pair(make_pair(lower_bound(X,X+n*2,xs[i]-W)-X,cs[i]),make_pair(lower_bound(Y,Y+n*2,ys[i]-H)-Y,lower_bound(Y,Y+n*2,ys[i]+H-1)-Y)); event[i<<1|1]=make_pair(make_pair(lower_bound(X,X+n*2,xs[i]+W)-X,-cs[i]),make_pair(lower_bound(Y,Y+n*2,ys[i]-H)-Y,lower_bound(Y,Y+n*2,ys[i]+H-1)-Y)); }sort(event,event+n*2); int ans=0; for(int i=0;i<n*2;i++){ update(event[i].second.first,event[i].second.second,event[i].first.second,1,0,n*2); ans=max(ans,T[1]); }printf("%d\n",ans); } int main(){ while(~scanf("%d%d%d",&n,&W,&H))solve(); return 0; }
愿你出走半生,归来仍是少年