2022-6-2[线段树] 区间和的个数,矩形面积 II

1. 区间和的个数

给你一个整数数组 nums 以及两个整数 lowerupper 。求数组中,值位于范围 [lower, upper] (包含 lowerupper)之内的 区间和的个数

区间和 S(i, j) 表示在 nums 中,位置从 ij 的元素之和,包含 ij (ij)。

Example 1
输入:nums = [-2,5,-1], lower = -2, upper = 2
输出:3
解释:存在三个区间:[0,0]、[2,2] 和 [0,2] ,对应的区间和分别是:-2 、-1 、2 。
Example 2
输入:nums = [0], lower = 0, upper = 0
输出:1
代码
class Solution {
private:
    vector<int> segTree;

    void build(unsigned int n) { segTree.assign(n << 2, 0); }

    void insert(int node, int start, int end, int val) {
        segTree[node]++;
        if (start == end) return;
        int mid = start + ((end - start) >> 1);
        int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
        val <= mid ? insert(left_node, start, mid, val) : insert(right_node, mid + 1, end, val);
    }

    int query(int start, int end, int L, int R, int node) {
        if (start > R || end < L) return 0;
        if (L <= start && end <= R) return segTree[node];
        int mid = start + ((end - start) >> 1);
        int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
        return query(start, mid, L, R, left_node) + query(mid + 1, end, L, R, right_node);
    }

public:
    int countRangeSum(vector<int> &nums, int lower, int upper) {
        vector<long long> preSum(nums.size() + 1, 0);
        for (int i = 0; i < nums.size(); ++i) preSum[i + 1] = preSum[i] + nums[i];

        set<long long> allNumbers;
        for (long long x: preSum) {
            allNumbers.insert(x);
            allNumbers.insert(x - lower);
            allNumbers.insert(x - upper);
        }

        unordered_map<long long, int> values; // 利用哈希表进行离散化
        int idx = 0;
        for (long long x: allNumbers) {
            values[x] = idx;
            idx++;
        }

        build(values.size());
        int ans = 0;
        for (long long x:preSum) {
            int L = values[x - upper], R = values[x - lower];
            ans += query(0, values.size() - 1, L, R, 0);
            insert(0, 0, values.size() - 1, values[x]);
        }
        return ans;
    }
};

2. 矩形面积 II

我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle [ i ] = [ x i 1 , y i 1 , x i 2 , y i 2 ] \text{rectangle}[i]=[x_{i1},y_{i1},x_{i2},y_{i2}] rectangle[i]=[xi1,yi1,xi2,yi2] ( x i 1 , y i 1 ) (x_{i1},y_{i1}) (xi1,yi1) 是该矩形 左下角 的坐标, ( x i 2 , y i 2 ) (x_{i2},y_{i2}) (xi2,yi2) 是该矩形 右上角 的坐标。

计算平面中所有 rectangles 所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次

返回 总面积 。因为答案可能太大,返回 1e9 + 7

Example 1

img

输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
输出:6
解释:如图所示,三个矩形覆盖了总面积为6的区域。
从(1,1)到(2,2),绿色矩形和红色矩形重叠。
从(1,0)到(2,3),三个矩形都重叠。
Example 2
输入:rectangles = [[0,0,1000000000,1000000000]]
输出:49
解释:答案是 1e18 对 (1e9 + 7) 取模的结果, 即 49 。
代码
// 不会。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值