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;
}
原文地址:https://www.cnblogs.com/RabbitHu/p/51nod1208.html