# 区间和的个数

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

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

 

示例 1:
输入:nums = [-2,5,-1], lower = -2, upper = 2
输出:3
解释:存在三个区间:[0,0]、[2,2] 和 [0,2] ,对应的区间和分别是:-2 、-1 、2 。

示例 2:

输入:nums = [0], lower = 0, upper = 0
输出:1

 

提示:

以下错误的选项是?

## aop ### before ```c #include using namespace std; ``` ### after ```c int main() { Solution sol; int res; vector nums = {-2, 5, -1}; int lower = -2; int upper = 2; res = sol.countRangeSum(nums, lower, upper); cout << res; return 0; } ``` ## 答案 ```c class Solution { public: int lower, upper, res; long tmp[10000]; void merge(vector &a, int l, int mid, int r) { int i = l, j = mid + 1, k = 0; while (i <= mid && j <= r) { if (a[i] <= a[j]) tmp[k++] = a[i++]; else tmp[k++] = a[j++]; } while (i <= mid) tmp[k++] = a[i++]; while (j <= r) tmp[k++] = a[j++]; copy(tmp, tmp + k, a.begin() + l); } void merge_sort(vector &a, int l, int r) { if (l >= r) return; int mid = l + r - l / 2; merge_sort(a, l, mid); merge_sort(a, mid + 1, r); int k = mid + 1, j = k; for (int i = l; i <= mid; ++i) { while (k <= r && a[k] - a[i] < lower) ++k; while (j <= r && a[j] - a[i] <= upper) ++j; res += j - k; } if (a[mid] <= a[mid + 1]) return; merge(a, l, mid, r); } int countRangeSum(vector &nums, int lower, int upper) { this->lower = lower; this->upper = upper; int n = nums.size(); vector presum(n + 1, 0); for (int i = 0; i < n; ++i) presum[i] = presum[i] + nums[i]; merge_sort(presum, 0, n); return res; } }; ``` ## 选项 ### A ```c class Solution { public: int countRangeSum(vector &nums, int lower, int upper) { int n = nums.size(); long presum = 0; multiset S; S.insert(0); int ret = 0; for (int i = 0; i < n; i++) { presum += nums[i]; ret += distance(S.lower_bound(presum - upper), S.upper_bound(presum - lower)); S.insert(presum); } return ret; } }; ``` ### B ```c class Solution { public: int countRangeSum(vector &nums, int lower, int upper) { int n = nums.size(); long presum = 0; vector S(n + 1, 0); int ret = 0; for (int i = 1; i <= n; i++) { presum += nums[i - 1]; for (int j = 1; j <= i; j++) { if (lower <= presum - S[j - 1] && presum - S[j - 1] <= upper) ret++; } S[i] = presum; } return ret; } }; ``` ### C ```c class Solution { public: int countRangeSum(vector &nums, int lower, int upper) { int count = 0; for (int i = 0; i < nums.size(); ++i) { if (nums[i] <= upper && nums[i] >= lower) ++count; long sum = nums[i]; for (int j = i + 1; j < nums.size(); ++j) { sum += nums[j]; if (sum <= upper && sum >= lower) ++count; } } return count; } }; ```