• 【POJ 2482】Stars in your window


    【原题题面】传送门

    【题面大意】

    给出每颗星星的坐标和亮度,在h,w的矩形范围内,内圈住的星星的最大亮度和。(边界上的星星不算)

    【题解大意】

    如何转化成扫描线问题?
    将每个星星能够产生贡献的范围设为矩形
    星星位于产生贡献的矩形的某个固定位置
    这样产生贡献的计算才不重不漏。

    具体操作:

    同样将每颗星星的用结构体(四元体)记录。

    每颗星星照例要用两个四元组储存,分别记录正贡献和负贡献

    线段树记录纵坐标的c值。

     查询任意区间长度为H,[i,i+H-1]中的和的最大值得出答案。 

    【code】

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define File "stars"
    #define ll long long
    inline void file(){
        freopen(File".in","r",stdin);
        freopen(File".out","w",stdout);
    }
    inline int read(){
        int x=0,f=1;   char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
        return x*f;
    }
    const int mxn = 1e4+5;
    int n,W,H;
    struct T{
        int l,r,dat,tg;
    }tr[mxn<<3];
    struct P{
        int x,y1,y2,c;
        bool operator <(const P t) const {
            return x == t.x ? c < t.c : x < t.x;
        }
    }p[mxn<<1];
    int a[mxn<<1];
    #define ls p<<1
    #define rs p<<1|1
    
    inline void B(int p,int l,int r){
        tr[p].l = l,tr[p].r = r;
        tr[p].dat = tr[p].tg = 0;
        if(l == r) return;
        int mid = l+r >>1;
        B(ls,l,mid),B(rs,mid+1,r);//!!!
    }
    inline void push(int p){
        int tg = tr[p].tg;
        if(tg){
            tr[ls].tg += tg;
            tr[rs].tg += tg;
            tr[ls].dat += tg;
            tr[rs].dat += tg;
            tr[p].tg = 0;
        }
    }
    inline void U(int p,int l,int r,int c){
        if(l <= tr[p].l && tr[p].r <= r){
            tr[p].dat += c;
            tr[p].tg += c;
            return;
        }
        push(p);
        int mid = tr[p].l+tr[p].r >>1;
        if(l <= mid) U(ls,l,r,c);
        if(r > mid) U(rs,l,r,c);
        tr[p].dat = max(tr[ls].dat,tr[rs].dat);
    }
    
    int main(){
    //    file();
        while(~scanf("%d%d%d",&n,&W,&H)){
    //        n = read(),W = read(),H = read();
            for(int i = 1;i <= n; ++i){
                int x,y,c;
                x = read(),y = read(),c = read();
    //            double x,y; int c;
    //            scanf("%lf %lf %d",&x,&y,&c);
                int id = i<<1;
                a[id-1] = y,a[id] = y+H-1;
                //储存y值
                p[id-1].x = x,p[id].x = x+W;
                p[id-1].y1 = p[id].y1 = y;
                p[id-1].y2 = p[id].y2 = y+H-1;
                p[id-1].c = c,p[id].c = -c;
            }
            n <<= 1;
    
            sort(a+1,a+n+1);//按y值排序,离散化
            int m = unique(a+1,a+n+1)-(a+1);
            for(int i = 1;i <= n; ++i){
                p[i].y1 = lower_bound(a+1,a+m+1,p[i].y1)-a;
                p[i].y2 = lower_bound(a+1,a+m+1,p[i].y2)-a;
            }
            sort(p+1,p+n+1);
    
            B(1,1,m);
            int ans = 0;
            for(int i = 1;i <= n; ++i){
                int y1 = p[i].y1,y2 = p[i].y2,c = p[i].c;
                U(1,y1,y2,c);
                ans = max(ans,tr[1].dat);
            }
            cout << ans << endl;
        }
        return 0;
    }
    /*
    3 5 4
    1 2 3
    2 3 2
    6 3 1
    3 5 4
    1 2 3
    2 3 2
    5 3 1
    */
    /*
    小数据点过了但大数据点没过
    可能是:
    1.没开ll或double爆精度
    2.算法本身有bug
    3.tle变成了wa
    4.mle变成了wa
    5.数组边界和更新
    6.变量的初值和变化
    */
    View Code
  • 相关阅读:
    架构漫谈阅读笔记(1)
    第一周学习进度
    2月13号寒假总结
    2月12日寒假总结
    2月11日寒假总结
    2月10日寒假总结
    寒假学习进度笔记一
    mapreduce课上实验
    个人课程总结
    用户体验评价
  • 原文地址:https://www.cnblogs.com/ve-2021/p/10875548.html
Copyright © 2020-2023  润新知