poj 2482 Stars in Your Window 线段树 扫描线

来源:互联网 发布:淘宝猎手软件 编辑:程序博客网 时间:2024/05/19 12:17

题目

题目链接:http://poj.org/problem?id=2482

题目来源:某人的线段树合集。

简要题意:天空中有些星星,它们有亮度,你拿个框来框星星,求框里星星亮度之和最大多少。

题解

这个题好理解然后做的时候灵光一现,不过想到做法之后很久之后才去写了。

线段树记录的是以某位置为起点的框里有多少亮度和

将星星转化为对[xw+1,x]内的位置增加/减少一个亮度,也就是区间更新。

求左边到哪里可以用尺取法直接线性做,二分也是可以的。

首先必然是要离散化的,我选择了对x,然后yh,y来离散化。因为y+h溢出,所以平移下。

y轴为基准建立扫描线,yh处加上一条线段,y处去掉。

然后每轮去对线段树的根去求结果就行了。

代码

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define fi first#define se secondusing namespace std;typedef long long LL;typedef pair<int,int> PII;// headconst int N = 1e5+5;struct Star {    int x, y, b;};struct Seg {    int x1, x2, add;    Seg(int x1, int x2, int add) : x1(x1), x2(x2), add(add) {}};struct SegmentTree {#define lson (rt<<1)#define rson ((rt<<1)|1)#define MID ((L+R)>>1)#define lsonPara lson, L, MID#define rsonPara rson, MID+1, R    const static int TN = N << 2;    int t[TN];    int lazy[TN];    void pushUp(int rt) {        t[rt] = max(t[lson], t[rson]);    }    void pushDown(int rt, int L, int R) {        if (lazy[rt]) {            lazy[lson] += lazy[rt];            lazy[rson] += lazy[rt];            t[lson] += lazy[rt];            t[rson] += lazy[rt];            lazy[rt] = 0;        }    }    void build(int rt, int L, int R) {        lazy[rt] = t[rt] = 0;        if (L == R) return;        build(lsonPara);        build(rsonPara);        pushUp(rt);    }    void modify(int rt, int L, int R, int l, int r, int v) {        if (l > R || r < L) return;        if (l <= L && r >= R) {            lazy[rt] += v;            t[rt] += v;        } else {            pushDown(rt, L, R);            modify(lsonPara, l, r, v);            modify(rsonPara, l, r, v);            pushUp(rt);        }    }};Star star[N];int x[N], y[N*2], l[N];vector<Seg> a[N*2];SegmentTree st;int main() {    int n, w, h;    while (scanf("%d%d%d", &n, &w, &h) == 3) {        for (int i = 0; i < n; i++) {            scanf("%d%d%d", &star[i].x, &star[i].y, &star[i].b);            x[i] = star[i].x;            y[i] = star[i].y - h, y[n+i] = star[i].y;        }        sort(x, x + n);        sort(y, y + 2 * n);        int xn = unique(x, x + n) - x;        int yn = unique(y, y + 2 * n) - y;        int lb = 0;        for (int i = 0; i < xn; i++) {            while (x[i] - x[lb] >= w) lb++;            l[i] = lb;        }        for (int i = 0; i < n; i++) {            int x2 = lower_bound(x, x + xn, star[i].x) - x;            int x1 = l[x2];            int y1 = lower_bound(y, y + yn, star[i].y - h) - y;            int y2 = lower_bound(y, y + yn, star[i].y) - y;            a[y1].push_back(Seg(x1, x2, star[i].b));            a[y2].push_back(Seg(x1, x2, -star[i].b));        }        st.build(1, 0, xn);        int ans = 0;        for (int i = 0; i < yn; i++) {            for (int j = 0; j < a[i].size(); j++) {                Seg &cur = a[i][j];                st.modify(1, 0, xn, cur.x1, cur.x2, cur.add);            }            ans = max(ans, st.t[1]);            a[i].clear();        }        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击