zoukankan      html  css  js  c++  java
  • 51nod 1208 窗上的星星 | 线段树 扫描线

    51nod 1208 Stars In Your Window

    题面

    整点上有N颗星星,每颗星星有一个亮度。用一个平行于x轴和y轴,宽为W高为H的方框去套星星。套住的所有星星的亮度之和为S(包括边框上的星星),求S的最大值。

    Input

    第1行:共3个数N, W, H,中间用空格分割,N为星星的数量,W为方框的宽度,H为方框的高度。(2 <= N <= 50000, 1 <= W, H <= 10^9)
    第2 - N + 1行:每行3个数,X, Y, L,中间用空格分隔,分别表示星星的横坐标X,纵坐标Y,以及星星的亮度L。(1 <= X, Y <= 10^9,1 <= L <= 10000)

    Output

    输出方框能够套住的最大亮度和S。

    Input示例

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

    Output示例

    12

    用一个矩形表示一颗星星,矩形宽W高H,左下角卡在原来星星的位置。当一个点被“星星矩形”覆盖时,这个点的权值就加上星星的亮度。这样,权值最大的位置就是矩形方块最佳放置位置的右上角。

    仍然是离散化后用扫描线做。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    using namespace std;
    typedef long long ll;
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define INF 0x3f3f3f3f
    
    template <class T>
    bool read(T &x){
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
            else if(c == EOF) return 0;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
        return 0;
    }
    template <class T>
    void write(T x){
        if(x < 0) x = -x, putchar('-');
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    
    const int N = 1000005;
    int n, ans, W, H, lstX[N], tmp[N], cntX;
    struct Query {
        int h, l, r, x;
        bool operator < (const Query &b) const{
            return h < b.h;
        }
    } q[N];
    void init(){
        read(n), read(W), read(H);
        for(int i = 1, x, y, z; i <= n; i++){
            read(x), read(y), read(z);
            q[2*i-1].l = q[2*i].l = lstX[2*i-1] = x;
            q[2*i-1].r = q[2*i].r = lstX[2*i] = x + W;
            q[2*i-1].h = y;
            q[2*i].h = y + H + 1;
            q[2*i-1].x = z;
            q[2*i].x = -z;
        }
        sort(lstX + 1, lstX + 2 * n + 1);
        for(int i = 1; i <= 2 * n; i++) tmp[i] = lstX[i];
        for(int i = 1; i <= 2 * n; i++)
            if(i == 1 || tmp[i] != tmp[i - 1])
                lstX[++cntX] = tmp[i];
    }
    int getX(int x){
        return lower_bound(lstX + 1, lstX + cntX + 1, x) - lstX;
    }
    int data[4*N], lazy[4*N];
    void pushdown(int k){
        data[k << 1] += lazy[k], data[k << 1 | 1] += lazy[k];
        lazy[k << 1] += lazy[k], lazy[k << 1 | 1] += lazy[k];
        lazy[k] = 0;
    }
    void change(int k, int l, int r, int ql, int qr, int x){
        if(ql <= l && qr >= r) return (void) (data[k] += x, lazy[k] += x);
        pushdown(k);
        int mid = (l + r) >> 1;
        if(ql <= mid) change(k << 1, l, mid, ql, qr, x);
        if(qr > mid) change(k << 1 | 1, mid + 1, r, ql, qr, x);
        data[k] = max(data[k << 1], data[k << 1 | 1]);
    }
    
    int main(){
        init();
        sort(q + 1, q + 2 * n + 1);
        for(int i = 1; i <= 2 * n; i++){
            if(i == 1 || q[i].h != q[i - 1].h)
                ans = max(ans, data[1]);
            change(1, 1, cntX, getX(q[i].l), getX(q[i].r), q[i].x);
        }
        write(ans), enter;
        return 0;
    }
    
  • 相关阅读:
    帝国cms字母导航功能制作教程
    HTML 学习
    DOM
    C# DataTable 使用原创
    GridView中编辑状态下实现DropDownList默认值(原创)
    C#精髓 GridView72大绝技(清清月儿)
    SQL注入攻击<收藏>
    Web网页安全色谱<收藏>
    GridView根据linkButton值不同跳转不同页面(原创)
    解决"Failed to access IIS metabase"
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/51nod1208.html
Copyright © 2011-2022 走看看