【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
", ans); 
	} 
    return 0; 
} 
原文地址:https://www.cnblogs.com/heyujun/p/10140285.html