题解:区间的个数
这道题首先的一个难点就是读懂题意
我首先读了几遍才明白了具体意思 意思如下:
根据例题输入:
也就是说在nums数组下标 0<=i<j<nums.size()中 寻找和区间
nums[j]+~nums[i]中 的值在lower和upper区间之间~
依此首先我们就会想到暴力法:
int count=0;
for(int i=0;i<nums.size();i++)
{
cout<<nums[i]<<" ";
long n=0;
for(int j=i;j<nums.size();j++)
{
n+=nums[j];
if(lower<=n&&n<=upper) count++;
}
}
return count;
但是呢,好歹这是一个困难题 哪有这么简单
很明显暴力法会超时~
于是我们可以转换思路
-
首先题目要求的是 lower<=区间[i,j]的和<=upper
-
可以转换成:lower<=sum.at(j)-sum.at(i)的和<=upper
-
通过变换:lower-sum.at(j)<=-sum.at(i)<=upper-sum.at(j)
-
去掉符号:**sum.at(j)-lower>=sum.at(i)>=sum.at(j)-upper **
-
所以最后关键东东来了 就是 sum.at(j)-upper <= sum.at(i) <= sum.at(j)-lower
-
我们于是想到了用
mutiset
自动排序的特性 -
并且mutiset 恰好有lower_bound,upper_bound这两个折半的查找函数~
-
最后通过distance来结合就可以了~
multiset<long> helper;
int count=0;
helper.insert(0);
long long sum=0;
for (int i:nums)
{
sum+=i;
count+=distance(helper.lower_bound(sum-upper),helper.upper_bound(sum-lower));
helper.insert(sum);
}
return count;