LeeCode 1498 二分 + 快速幂

题意

传送门 LeeCode 1498. 满足条件的子序列数目

题解

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(targetx),若该值小于等于当前元素,则不存在这样的子序列;反之,考虑以 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(xy<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} 2n2;设 [ 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 2n2+2n3++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} 2n11+1=2n1

快速幂求解即可。

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值