题意
题解
求 n u m s nums nums 中能满足其最小元素与最大元素的和小于或等于 t a r g e t target target 的非空子序列的数目,则答案与原数组顺序无关。
排序 n u m s nums nums,遍历数组,二分求以当前元素 x x x 为最小元素的子序列的和满足条件时,序列最大元素元素的 u p p e r _ b o u n d ( t a r g e t − x ) upper\_bound(target-x) upper_bound(target−x),若该值小于等于当前元素,则不存在这样的子序列;反之,考虑以 y ( x ≤ y < u p p e r _ b o u n d ( t a r g e t ) y(x\leq y<upper\_bound(target) y(x≤y<upper_bound(target) 为最大值的子序列,对于序列中的其他元素 z ( x < z < y ) z(x<z<y) z(x<z<y) 可以取与不取,设 [ x , y ] [x,y] [x,y] 的元素数量为 n ′ n' n′,则子序列数量为 2 n ′ − 2 2^{n'-2} 2n′−2;设 [ x , u p p e r _ b o u n d ( t a r g e t ) ) [x, upper\_bound(target)) [x,upper_bound(target)) 的元素数量为 n n n,则以 x x x 为最小元素的子序列数量为
2 n − 2 + 2 n − 3 + ⋯ + 2 0 2^{n-2}+2^{n-3}+\dots +2^0 2n−2+2n−3+⋯+20
式中最后一项为 n = 2 n=2 n=2,即子序列只有 2 2 2 个元素的情况;考虑子序列数量为 1 1 1,即子序列中仅有 x x x,则满足条件的以 x x x 为最小元素的子序列数为
2 n − 1 − 1 + 1 = 2 n − 1 2^{n-1}-1+1=2^{n-1} 2n−1−1+1=2n−1
快速幂求解即可。
class Solution
{
public:
int mod = 1000000007;
int qpow(long long x, int n)
{
if (n < 0) return 0;
long long res = 1;
while (n)
{
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int numSubseq(vector<int> &nums, int target)
{
int res = 0;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++)
{
int n = upper_bound(nums.begin(), nums.end(), target - nums[i]) - (nums.begin() + i);
res = (res + qpow(2, n - 1)) % mod;
}
return res;
}
};