leetcode 850. 矩形面积 II 【矩形面积并】【线段树】【扫描线】

我们给出了一个(轴对齐的)矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标,(x2,y2)是该矩形右上角的坐标。

找出平面中所有矩形叠加覆盖后的总面积。 由于答案可能太大,请返回它对 10 ^ 9 + 7 取模的结果。

示例 1:

输入:[[0,0,2,2],[1,0,2,3],[1,0,3,1]]
输出:6
解释:如图所示。
示例 2:

输入:[[0,0,1000000000,1000000000]]
输出:49
解释:答案是 10^18 对 (10^9 + 7) 取模的结果, 即 (10^9)^2 → (-7)^2 = 49 。
提示:

1 <= rectangles.length <= 200
rectanges[i].length = 4
0 <= rectangles[i][j] <= 10^9
矩形叠加覆盖后的总面积不会超越 2^63 - 1 ,这意味着可以用一个 64 位有符号整数来保存面积结果。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rectangle-area-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    struct node{
        long long x, y, h;
        int flag;
        node() {};
        node(long long x, long long y, long long h, int flag): x(x), y(y), h(h), flag(flag) {}
        bool operator < (const node &a) const{
            return h < a.h;
        }
    } e[5000];
    
    int cover[50000];
    long long sum[50000];
    int X[50000];
    
    void pushup(int rt, int l, int r) {
        if(cover[rt]) sum[rt] = X[r + 1] - X[l];
        else if(l == r) sum[rt] = 0;
        else sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]) % 1000000007;
    }
    
    void update(int rt, int l, int r, int x, int y, int v) {
        if(x <= l && r <= y) {
            cover[rt] += v;
            pushup(rt, l, r);
            return;
        }
        int mid = (l + r) >> 1;
        if(x <= mid) update(rt << 1, l, mid, x, y, v);
        if(mid < y) update(rt << 1 | 1, mid + 1, r, x, y, v);
        pushup(rt, l, r);
    }
    
    int rectangleArea(vector>& rectangles) {
        int cnt = 0;
        long long ans = 0;
        memset(cover, 0, sizeof cover);
        memset(sum, 0, sizeof sum);
        memset(X, 0, sizeof X);
        for(int i = 0; i < rectangles.size(); i++) {
            e[cnt] = node(rectangles[i][0], rectangles[i][2], rectangles[i][1], 1);
            X[cnt++] = rectangles[i][0];
            e[cnt] = node(rectangles[i][0], rectangles[i][2], rectangles[i][3], -1);
            X[cnt++] = rectangles[i][2];
        }
        sort(e, e + cnt);
        sort(X, X + cnt);
        for(int i = 0; i < cnt; i++) {
            int l = lower_bound(X, X + cnt, e[i].x) - X;
            int r = lower_bound(X, X + cnt, e[i].y) - X - 1;
            update(1, 0, cnt - 1, l, r, e[i].flag);
            long long tem = (e[i + 1].h - e[i].h) * sum[1] % 1000000007;
            ans = (ans + tem) % 1000000007;
        }
        return ans;
    }
};

 

你可能感兴趣的:(线段树)