poj 2482 Stars in Your Window(线段树,扫描线)

来源:互联网 发布:windows10如何卸载软件 编辑:程序博客网 时间:2024/05/06 19:41


poj 2482 Stars in Your Window


题意,移动一个固定大小的矩形,使矩形中的星星亮度之和最大(边框上的不算),输出该值


这个题把可移动的矩形转换为扫描线的方式来做非常巧妙,以每颗星星(亮度为val)为左下角建立一个矩形(向Y轴映射),左竖边的值就为val,右竖边的值为-val,试想一下如果有两个矩形有重叠部分的话那么这两个矩形所代表的两颗星星必定能被一个矩形圈在一起,这样我们就能利用扫描线求出重叠部分的值。

离散化后进行扫描线操作,每个节点Lazy维护一个最大值maxval,这样每一次插入一条线在根节点就保存得有当前整棵树最大值,即当前矩形能圈住的最大值。

需要注意的:

因为边框上的星星不算在矩形内,所以排序的时候在x坐标相同的情况下,val值小的应在前面

我的写法中可能有中间结果超int,导致出现负数,然后一直RE啊RE(吐血)、、、本来可以1A的,一怒之下全改成long long、、、


#include<cstdio>#include<cstring>#include<map>#include<algorithm>#include<iostream>using namespace std;#define ll long long#define MAXN 200100#define lch p<<1#define rch p<<1|1struct ele{    ll x,yd,yu;    ll val;    bool operator < (const ele &a) const    {        if(x==a.x)            return val<a.val;        else return x<a.x;    }}seg[MAXN*4];struct node{    ll l,r;    ll val;    ll maxval;}t[MAXN*8];ll max(ll a,ll b) {return a>b?a:b;}void construct(ll l,ll r,ll p){    t[p].l=l,t[p].r=r;    t[p].val=t[p].maxval=0;    if(r-l<=1) return ;    ll m=(l+r)>>1;    construct(l,m,lch);    construct(m,r,rch);}void pushdown(ll p){    t[lch].val+=t[p].val;    t[rch].val+=t[p].val;    t[lch].maxval+=t[p].val;    t[rch].maxval+=t[p].val;    t[p].val=0;}void modify(ll l,ll r,ll val,ll p){    if(t[p].l==l&&t[p].r==r)    {        t[p].maxval+=val;        t[p].val+=val;        return ;    }        if(t[p].val) pushdown(p);        ll m=(t[p].l+t[p].r)>>1;    if(r<=m) modify(l,r,val,lch);    else if(l>=m) modify(l,r,val,rch);    else modify(l,m,val,lch),modify(m,r,val,rch);        t[p].maxval=max(t[lch].maxval,t[rch].maxval);}ll yy[MAXN*4];map<ll,ll> rec;int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    ll i,n,w,h,x,y,val;    while(scanf("%lld%lld%lld",&n,&w,&h)!=EOF)    {        for(i=0;i<(n<<1);i+=2)        {            scanf("%lld%lld%lld",&x,&y,&val);            seg[i].x=x,seg[i].yd=y,seg[i].yu=y+h,seg[i].val=val;            seg[i+1].x=x+w,seg[i+1].yd=y,seg[i+1].yu=y+h,seg[i+1].val=-val;            yy[i]=y;            yy[i+1]=y+h;        }        sort(seg,seg+(n<<1));        sort(yy,yy+(n<<1));        ll up=(int)(unique(yy,yy+(n<<1))-yy);        rec.clear();        for(i=0;i<up;i++)            rec[yy[i]]=i;//printf("%d\n",yy[i]);        ll ans=0;        construct(0,up,1);        for(i=0;i<(n<<1);i++)        {            modify(rec[seg[i].yd],rec[seg[i].yu],seg[i].val,1);            ans=max(ans,t[1].maxval);        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击