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;
}
posted @ 2017-03-14 13:05  forever97  阅读(156)  评论(0编辑  收藏  举报