POJ 2482 Stars in Your Window(线段树)
POJ 2482 Stars in Your Window
题意:给定一些星星,每一个星星都有一个亮度。如今要用w * h的矩形去框星星,问最大能框的亮度是多少
思路:转化为扫描线的问题,每一个星星转化为一个矩形,那么等于求矩形相交区域值最大的区域,利用线段树去维护就可以
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 10005; int n, w, h; struct Line { ll l, r, y, c; Line() {} Line(ll l, ll r, ll y, ll c) { this->l = l; this->r = r; this->y = y; this->c = c; } } line[N * 2]; bool cmp(Line a, Line b) { if (a.y == b.y) return a.c < b.c; return a.y < b.y; } ll hash[N * 2]; int hn; int find(ll x) { return lower_bound(hash, hash + hn, x) - hash; } #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) struct Node { int l, r; ll add, sum; } node[N * 8]; void build(int l, int r, int x = 0) { node[x].l = l; node[x].r = r; node[x].add = node[x].sum = 0; if (l == r) return; int mid = (l + r) / 2; build(l, mid, lson(x)); build(mid + 1, r, rson(x)); } void pushup(int x) { if (node[x].l == node[x].r) node[x].sum = node[x].add; else node[x].sum = max(node[lson(x)].sum, node[rson(x)].sum) + node[x].add; } void add(int l, int r, ll c, int x = 0) { if (node[x].l >= l && node[x].r <= r) { node[x].add += c; pushup(x); return; } int mid = (node[x].l + node[x].r) / 2; if (l <= mid) add(l, r, c, lson(x)); if (r > mid) add(l, r, c, rson(x)); pushup(x); } int main() { while (~scanf("%d%d%d", &n, &w, &h)) { ll x1, y1, x2, y2, c; for (int i = 0; i < n; i++) { scanf("%lld%lld%lld", &x1, &y1, &c); x2 = x1 + w; y2 = y1 + h; hash[i * 2] = x1; hash[i * 2 + 1] = x2; line[i * 2] = Line(x1, x2, y1, c); line[i * 2 + 1] = Line(x1, x2, y2, -c); } n *= 2; hn = 1; sort(hash, hash + n); for (int i = 1; i < n; i++) if (hash[i] != hash[i - 1]) hash[hn++] = hash[i]; build(0, hn - 2); sort(line, line + n, cmp); ll ans = 0; for (int i = 0; i < n; i++) { add(find(line[i].l), find(line[i].r) - 1, line[i].c); ans = max(ans, node[0].sum); } printf("%lld\n", ans); } return 0; }