【POJ2482】Stars in Your Window

【POJ2482】Stars in Your Window

题面

vjudge

题解

第一眼还真没发现这题居然™是个扫描线
令点的坐标为\((x,y)\)权值为\(c\),则
若这个点能对结果有\(c\)的贡献,必须要矩形左下角的点的范围必须在\(([x,x+w),[y,y+h))\)之间
则按扫描线套路将一个类似矩形的范围拆成线\((x,y1,y2,c)\)\((x+w,y1,y2,-c)\)(依次表示横坐标、下端点纵坐标、上端点纵坐标、权值)即可
最后注意排序时不但要按\(x\)排,也要按权值排

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> 
using namespace std;
typedef long long ll; 
const int MAX_N = 100005; 
ll N, W, H; 
struct rec { ll x, y, _y, k; } t[MAX_N << 1]; int cnt;
inline bool cmp_x (const rec &a, const rec &b) { 
    if (a.x == b.x) return a.k < b.k; 
    else return a.x < b.x; 
} 
ll X[MAX_N << 2], size = 0;
#define lson (o << 1)
#define rson (o << 1 | 1) 
ll mx[MAX_N << 3], tag[MAX_N << 3]; 
void puttag(int o, ll v) { mx[o] += v, tag[o] += v; }
void pushup(int o) { mx[o] = max(mx[lson], mx[rson]) + tag[o]; }
void build(int o, int l, int r) {
    mx[o] = tag[o] = 0; 
    if (l == r) return ; 
    int mid = (l + r) >> 1; 
    build(lson, l, mid); build(rson, mid + 1, r); 
} 
void modify(int o, int l, int r, int ql, int qr, ll v) { 
    if (ql <= l && r <= qr) return (void)puttag(o, v); 
    int mid = (l + r) >> 1; 
    if (ql <= mid) modify(lson, l, mid, ql, qr, v); 
    if (qr > mid) modify(rson, mid + 1, r, ql, qr, v);
    pushup(o); 
} 
int main () {
    while (scanf("%lld%lld%lld", &N, &W, &H) != EOF) { 
        cnt = 0; size = 0; 
        for (int i = 1; i <= N; i++) { 
            ll x, y, c; scanf("%lld%lld%lld", &x, &y, &c); 
            t[++cnt].x = x, t[cnt].y = y, t[cnt]._y = y + H, t[cnt].k = c; 
            t[++cnt].x = x + W, t[cnt].y = y, t[cnt]._y = y + H, t[cnt].k = -c; 
            X[++size] = x, X[++size] = x + W, X[++size] = y, X[++size] = y + H; 
        } 
        sort(&X[1], &X[size + 1]); size = unique(&X[1], &X[size + 1]) - X - 1; 
        sort(&t[1], &t[cnt + 1], cmp_x); 
        build(1, 1, size - 1); 
        ll ans = 0; 
        for (int i = 1; i <= cnt; i++) { 
            int l = lower_bound(&X[1], &X[size + 1], t[i].y) - X;
            int r = lower_bound(&X[1], &X[size + 1], t[i]._y) - X - 1; 
            modify(1, 1, size - 1, l, r, t[i].k); 
            ans = max(ans, mx[1]); 
        }
        printf("%lld\n", ans); 
    } 
    return 0; 
} 

猜你喜欢

转载自www.cnblogs.com/heyujun/p/10140285.html