POJ 2482 Stars in Your Window(线段树扫描线)

来源:互联网 发布:快速充电器软件下载 编辑:程序博客网 时间:2024/05/17 20:32

题意:

给出星星的坐标和亮度,给定一个矩形(/),求框住的星星亮度和的最大值,恰好在边上的不算

对于每颗星星我们以左下角构成一个矩形两条边一条范围[x,x+w),高度为y,权值为brightness,另一条范围[x,x+w),高度为y+h,亮度为-brightness。样我们对所有边进行排序从低到高扫描就行了计算线段最大覆盖次数即可

#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>using namespace std;#define MID(x,y) ( ( x + y ) >> 1 )  #define L(x) ( x << 1 )  #define R(x) ( x << 1 | 1 )  #define FOR(i,s,t) for(int i=s; i<t; i++)  using namespace std;const int MAX = 20010;struct point { int x, y; long long lx, ly, rx, ry; int val; };point p[MAX / 2];long long x[MAX], y[MAX];int ans;struct Sline { int x, y1, y2; int flag; };Sline l[MAX];void add_line(int x1, int y1, int x2, int y2, int &cnt, int flag){l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;l[cnt++].flag = flag;l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;l[cnt++].flag = -flag;}bool cmp(Sline a, Sline b){if (a.x == b.x) return a.flag < b.flag;return a.x < b.x;}struct Tnode {               // 一维线段树   int l, r, val, max;int len() { return r - l; }int mid() { return MID(l, r); }bool in(int ll, int rr) { return l >= ll && r <= rr; }void lr(int ll, int rr) { l = ll; r = rr; }};Tnode node[MAX << 2];void Build(int t, int l, int r){node[t].val = node[t].max = 0;node[t].lr(l, r);if (node[t].len() == 1) return;int mid = MID(l, r);Build(L(t), l, mid);Build(R(t), mid, r);}void Updata(int t, int l, int r, int val){if (node[t].in(l, r)){node[t].val += val;node[t].max += val;ans = max(node[t].max, ans);return;}if (node[t].len() == 1) return;node[L(t)].val += node[t].val;node[L(t)].max += node[t].val;node[R(t)].val += node[t].val;node[R(t)].max += node[t].val;node[t].val = 0;int mid = node[t].mid();if (l >= mid)Updata(R(t), l, r, val);elseif (r <= mid)Updata(L(t), l, r, val);else{Updata(L(t), l, r, val);Updata(R(t), l, r, val);}node[t].max = max(node[L(t)].max, node[R(t)].max);ans = max(node[t].max, ans);}int solve(int cx, int cy, int n){sort(x, x + cx);sort(y, y + cy);cx = unique(x, x + cx) - x;cy = unique(y, y + cy) - y;int cnt = 0;FOR(i, 0, n){int x2 = lower_bound(x, x + cx, p[i].rx) - x;int y2 = lower_bound(y, y + cy, p[i].ry) - y;int x1 = lower_bound(x, x + cx, p[i].lx) - x;int y1 = lower_bound(y, y + cy, p[i].ly) - y;add_line(x1, y1, x2, y2, cnt, p[i].val);}sort(l, l + cnt, cmp);Build(1, 0, cy + 1);FOR(i, 0, cnt)Updata(1, l[i].y1, l[i].y2, l[i].flag);return ans;}int main(){int l;int n, w;while (scanf("%d%d%d", &n, &w, &l) != EOF){int cntx = 0, cnty = 0;ans = 0;FOR(i, 0, n){scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].val);p[i].lx = p[i].x; p[i].ly = p[i].y;p[i].rx = p[i].x * 1ll + w; p[i].ry = p[i].y * 1ll + l;x[cntx++] = p[i].lx;x[cntx++] = p[i].rx;y[cnty++] = p[i].ly;y[cnty++] = p[i].ry;}solve(cntx, cnty, n);printf("%d\n", ans);}return 0;}


原创粉丝点击