zoukankan      html  css  js  c++  java
  • ACWing 248. 窗内的星星|扫描线+懒惰标记

    传送门

    题目描述

    在一个天空中有很多星星(看作平面直角坐标系),已知每颗星星的坐标和亮度(都是整数)。

    求用宽为W、高为H的矩形窗户(W,H为正整数)能圈住的星星的亮度总和最大是多少。(矩形边界上的星星不算)

    输入格式

    输入包含多组测试用例。

    每个用例的第一行包含3个整数:n,W,H,表示星星的数量,矩形窗口的宽和高。

    然后是n行,每行有3个整数:x,y,c,表示每个星星的位置(x,y)和亮度。

    没有两颗星星在同一点上。

    输出格式

    每个测试用例输出一个亮度总和最大值。

    每个结果占一行。

    数据范围

    1≤n≤10000,
    1≤W,H≤1000000,
    10≤x,y<231

    输入样例:

    3 5 4
    1 2 3
    2 3 2
    6 3 1
    3 5 4
    1 2 3
    2 3 2
    5 3 1
    

    输出样例:

    5
    6
    

    题解:https://www.cnblogs.com/l999q/p/11366840.html可参考这篇博客,不同点在于它是维护亮度和(相当于维护那篇博客中的最大cnt值)。

    要注意的是:

    1. 题目中说矩形边界上的星星不算,那么我们线段的上边界要减一(存边界的四元组的时候处理)。
    2. 若一个矩形的右边界与另一个矩形的左边界重合时,先减去左边矩阵的亮度再加上右边矩阵的亮度。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N = 2e4 + 10;
    struct node{
        int x,y1,y2,val;
        node() {}
        node(int x, int y1, int y2,int val){
            this->x = x; this->val = val;
            this->y1 = y1; this->y2 = y2;
        }
        bool operator <(const node &t)const {
            return x<t.x;
        }
    };
    struct Tree{
        int l,r;
        int val,lazy;
    }t[N<<2];
    vector<node> a;
    vector<int> v;
    void build(int rt,int l,int r) {
        t[rt].l = l,t[rt].r = r;
        t[rt].val = 0; t[rt].lazy = 0;
        if (l == r) return;
        int mid = (l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
    }
    void update(int rt,int l,int r,int val) {
        if (l <= t[rt].l && r >= t[rt].r) {
            t[rt].val += val;
            t[rt].lazy += val;
            return;
        }
        if (t[rt].lazy) {
            t[rt<<1].val += t[rt].lazy;
            t[rt<<1].lazy += t[rt].lazy;
            t[rt<<1|1].val += t[rt].lazy;
            t[rt<<1|1].lazy += t[rt].lazy;
            t[rt].lazy = 0;
        }
        int mid = (t[rt].l+t[rt].r)>>1;
        if (l <= mid) update(rt<<1,l,r,val);
        if (r > mid) update(rt<<1|1,l,r,val);
        t[rt].val = max(t[rt<<1].val,t[rt<<1|1].val);
    }
    int main() {
        int n,w,h;
        while (~scanf("%d%d%d",&n,&w,&h) ) {
            v.clear();a.clear();
            for(int i = 0; i < n; i++) {
                int x,y,c;
                scanf("%d%d%d",&x,&y,&c);
                v.push_back(y);
                v.push_back(y+h-1);
                a.push_back(node(x,y,y+h-1,c));
                a.push_back(node(x+w,y,y+h-1,-c)); // y坐标边界要减,x坐标不要减
            }
            v.push_back(-1);
            sort(a.begin(),a.end());
            sort(v.begin(),v.end());
            v.erase(unique(v.begin(),v.end()),v.end());
            n=v.size();
            build(1,0,n);
            int ans = 0;
            for (int i = 0; i < n; i++) {
                int l = lower_bound(v.begin(),v.end(),a[i].y1) - v.begin();
                int r = lower_bound(v.begin(),v.end(),a[i].y2) - v.begin();
                update(1,l,r,a[i].val);
                if (a[i].val>0) ans = max(ans,t[1].val);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    jquery1.9之学习笔记
    ERROR: Removing 'hello': Device or resource busy
    windows虚拟机性能调整
    kvm虚拟机控制台登录配置
    KVM虚拟机的管理
    window kvm 虚拟机的创建
    kvm虚拟化环境的搭建
    C实现哈希表
    哲学家就餐问题 C语言实现
    Linux面试题
  • 原文地址:https://www.cnblogs.com/l999q/p/11366867.html
Copyright © 2011-2022 走看看