# 区间和的个数
给你一个整数数组 nums
以及两个整数 lower
和 upper
。求数组中,值位于范围 [lower, upper]
(包含 lower
和 upper
)之内的 区间和的个数 。
区间和 S(i, j)
表示在 nums
中,位置从 i
到 j
的元素之和,包含 i
和 j
(i
≤ j
)。
示例 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
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
-105 <= lower <= upper <= 105
- 题目数据保证答案是一个 32 位 的整数
以下错误的选项是?
## 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;
}
};
```