您的位置:首页 > 其它

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

2017-10-19 21:31 423 查看
题意:

给出星星的坐标和亮度,给定一个矩形(长/宽),求框住的星星亮度和的最大值,恰好在边上的不算。
对于每颗星星,我们以左下角构成一个矩形,两条边:一条范围[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);
else
if (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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: