zoukankan      html  css  js  c++  java
  • POJ 2482 Stars in Your Window(扫描线 + 线段树 区域统计)

    题意:

    统计给定大小矩形区间范围内星星的最大亮度。

    思路:

    1. 对 x 坐标离散化,并且对 y 坐标从小到大排序。

    2. 枚举 x 坐标,作 [x, x + W) 的扫描线,并且同时对于 y 方向增加,控制在 H 范围内,即以 x 为左下坐标作 W * H 的矩形。

    3. 要有 2 组标记 : segmax 表示矩形内所能达到的最大亮度,lab 标记在 pushDown 会发挥作用。

    问题的关键在于控制 W * H 的矩阵以及对于边界的控制,举例子点 [1, 3] 其实只有两个线段,所以代码中线段树所代表的扫描线的范围是 1, 2

    也就是说线段树中的节点代表的是线段,而非坐标,弄清楚这点,所有边界问题迎刃而解。

     

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define lhs l, m, rt << 1
    #define rhs m + 1, r, rt << 1 | 1
    
    #define LL long long int 
    
    const int maxn = 30010;
    int segmax[maxn << 2], lab[maxn << 2];
    LL xcord[maxn];
    
    structStar {
        LL x, y;
        int value;
    
        Star() { }
        Star(LL _x, LL _y, int _v) 
            : x(_x), y(_y), value(_v) { }
    
        bool operator < (const Star& other)
        { return y < other.y; }
    } star[maxn] ;
    
    void pushUp(int rt)
    {
        segmax[rt] = max(segmax[rt << 1], segmax[rt << 1 | 1]);
    }
    
    void pushDown(int rt)
    {
        if (lab[rt])
        {
            lab[rt << 1] += lab[rt];
            lab[rt << 1 | 1] += lab[rt];
            segmax[rt << 1] += lab[rt];
            segmax[rt << 1 | 1] += lab[rt];
            lab[rt] = 0;
        }
    }
    
    void update(int beg, int end, int value, int l, int r, int rt)
    {
        if (beg <= l && r <= end)
        {
            lab[rt] += value;
            segmax[rt] += value;
            return ;
        }
        pushDown(rt);
    
        int m = (l + r) >> 1;
        if (beg <= m)
            update(beg, end, value, lhs);
        if (end > m)
            update(beg, end, value, rhs);
    
        pushUp(rt);
    }
    
    int main()
    {
        int n, W, H;
        while (scanf("%d %d %d", &n, &W, &H) != EOF)
        {
            int m = 0, ret = 0;
            for (int i = 0; i < n; ++i)
            {
                scanf("%lld %lld %d", &star[i].x, &star[i].y, &star[i].value);
                xcord[m++] = star[i].x;
                xcord[m++] = star[i].x + W;
            }
            sort(xcord, xcord + m);
            sort(star, star + n);
    
            m = unique(xcord, xcord + m) - xcord;
    
            memset(segmax, 0, sizeof(segmax));
            memset(lab, 0, sizeof(lab));
    
            for (int i = 0, j = 0; i < n; ++i)
            {
                int beg = lower_bound(xcord, xcord + m, star[i].x) - xcord;
                int end = lower_bound(xcord, xcord + m, star[i].x + W) - xcord - 1;
                update(beg, end, star[i].value, 0, m - 1, 1);
    
                while (j <= i && star[i].y - star[j].y >= H)
                {
                    beg = lower_bound(xcord, xcord + m, star[j].x) - xcord;
                    end = lower_bound(xcord, xcord + m, star[j].x + W) - xcord - 1;
                    update(beg, end, -star[j++].value, 0, m - 1, 1);
                }
    
                ret = max(ret, segmax[1]);
            }
            printf("%d\n", ret);
        }
        return 0;
    }
  • 相关阅读:
    Ubuntu14.04手动安装配置jdk sdk ndk ant
    Ubuntu中(桌面或者文件夹)右键鼠标打开终端设置
    C语言中固定长度和不定长度的数组初始化示例
    Algorithm Design——最大公约数、最小公倍数
    Algorithm Design——凸包
    Algorithm Design——判断线段是否相交
    Algorithm Design Everyday——2.查找学生信息
    Algorithm Design——查找
    Algorithm Design——高精度整数四则运算
    Algorithm Design——并查集
  • 原文地址:https://www.cnblogs.com/kedebug/p/2890560.html
Copyright © 2011-2022 走看看