【POJ2482】Stars in Your Window
阿新 • • 發佈:2018-12-18
【POJ2482】Stars in Your Window
題面
題解
第一眼還真沒發現這題居然™是個掃描線
令點的座標為\((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; }