poj 2482 Stars in Your Window 扫描线 线段树

题意:

给你n个星星,每个星星有不同的亮度,让你用N*M的矩形去套,如何套得最大亮度

分析:

因为题意用固定矩形去套那么对于每一个星星我们都可以建立一个矩形让后求矩形并的最大值

如图:


当然这些线还有其亮度,所以套最多的不一定最大

我们需要2个数组 cnt【】维护当前区间的亮度maxx【】区间内最亮的亮度

其中push_up()  maxx[st]=max(maxx[tmp],maxx[tmp|1])+cnt[st];

注意当星星在框上的时候不算

对于这种我们只需要把N,M各减去0.1再加入线段坐标就行惹

ACcode:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 20002
#define tmp (st<<1)
#define mid ((l+r)>>1)
#define lson l,mid,tmp
#define rson mid+1,r,tmp|1
using namespace std;
struct Seg{
    double h,l,r;
    int s;
    Seg(){}
    Seg(double a,double b,double c,int d):l(a),r(b),h(c),s(d){}
    bool operator <(const Seg &cmp)const{
        if(h==cmp.h)return s<cmp.s;
        return h<cmp.h;
    }
}ss[maxn<<2];
int maxx[maxn<<2],cnt[maxn<<2];
double x[maxn];
int ans;
void push_up(int st){
    maxx[st]=max(maxx[tmp],maxx[tmp|1])+cnt[st];
}
void update(int L,int R,int c,int l,int r,int st){
    if(L<=l&&r<=R){
        maxx[st]+=c;
        cnt[st]+=c;
        return ;
    }
    if(L<=mid)update(L,R,c,lson);
    if(R>mid)update(L,R,c,rson);
    push_up(st);
}
int main(){
    int n;
    double xx,yy;
    while(scanf("%d%lf%lf",&n,&xx,&yy)!=EOF){
        xx-=0.1;
        yy-=0.1;
        int a,b,c,m=0;
        for(int i=1;i<=n;++i){
            scanf("%d%d%d",&a,&b,&c);
            x[m]=a;
            ss[m++]=Seg(a,a+xx,b,c);
            x[m]=a+xx;
            ss[m++]=Seg(a,a+xx,b+yy,-c);
        }
        sort(x,x+m);
        sort(ss,ss+m);
        ans=-0x3f3f3f3f;
        for(int i=0;i<m;++i){
            int l=lower_bound(x,x+m,ss[i].l)-x;
            int r=lower_bound(x,x+m,ss[i].r)-x-1;
            update(l,r,ss[i].s,0,m,1);
            ans=max(ans,maxx[1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值