zoukankan      html  css  js  c++  java
  • 窗内的星星

    题目链接

    题意:已知每个星星的坐标和亮度,求用一个宽w,高h的矩形能圈住的星星的亮度总和最大是多少。

    思路:我们把每个星星置为w,h矩形的左下角,这样围才是最多的情况。然后将每个这样的搞出来并把其矩形赋权为其亮度,可以发现当两个矩形重合的地方就可以用亮度加起来

    表示,因为在那个地方做宽w高h的矩形两个星星都圈的起来。所以问题就又变成了求坐标上重叠区域的最大权值和。

    根据扫描线,我们先对x坐标排序,设星星(x,y,c)c为亮度,保存两个四元组(x,y,y+h-1,c)和(x+w,y,y+h-1,-c)。维护对于当前x,y坐标整点上权值和的最大值。区间修改+c,-c就相当于

    只在x到x+c的区间内亮度+c。

    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<queue>
    #include<cstdio>
    #include<cmath>
    #define int long long
    #define lowbit(x) x&(-x)
    using namespace std;
    const int N=2e4+10;
    struct node{
        int x,y1,y2;
        int c;
        node() {}
        node(int x, int y1,int y2,int c){
            this->x = x; this->c = c;
            this->y1 = y1; this->y2 = y2;
        }
        bool operator <(const node &t)const {
            return x<t.x;
        }
    }a[N];
    int n,w,h,y[N];
    struct Tree
    {
        int l,r;
        int len,lazy;
    }t[N<<2];
    void pushup(int p)
    {
        t[p].len=max(t[p<<1].len,t[p<<1|1].len)+t[p].lazy;
    }
    void build(int p,int l,int r)
    {
        t[p].l=y[l];
        t[p].r=y[r];
        t[p].lazy=0;
        t[p].len=0;
        if(r-l==1)
        {
            return;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid,r);
    }
    void update(int l,int r,int k,int p)
    {
        if(t[p].l>=l&&t[p].r<=r)
        {
            t[p].lazy+=k;
            t[p].len+=k;
            return;
        }
        if(l<t[p<<1].r)
            update(l,min(r,t[p<<1].r),k,p<<1);
        if(r>t[p<<1|1].l)
            update(max(l,t[p<<1|1].l),r,k,p<<1|1);
        pushup(p);
    }
    signed main()
    {
        while(~scanf("%lld%lld%lld",&n,&w,&h))
        {
            int cnt=0,num=1;
            for(int i=1;i<=n;i++)
            {
                int xx,yy,k;
                scanf("%lld%lld%lld",&xx,&yy,&k);
                a[cnt++]=node(xx,yy,yy+h,k);
                a[cnt++]=node(xx+w,yy,yy+h,-k);
                y[num++]=yy;
                y[num++]=yy+h;
            }
            sort(y+1,y+num);
            int ans=0;
            num=unique(y+1,y+num)-(y+1);
            sort(a,a+cnt);
            build(1,1,num);
            for(int i=0; i<cnt; i++)
            {
                update(a[i].y1,a[i].y2,a[i].c,1);
                if(a[i].c>0)
                    ans=max(ans,t[1].len);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    一线架构师实践指南读后感
    可修改性战术
    软件架构师如何工作?
    寒假学习第十五天
    寒假学习第十四天
    寒假学习第十三天
    寒假学习第十二天
    寒假学习第十一天
    寒假学习第十天
    如何变得聪明
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/11368976.html
Copyright © 2011-2022 走看看