1498. 满足条件的子序列数目 二分 快速幂 等比数列前n项和公式

先排序

从后向前,大于target / 2 的数,求出最后一个小于等于target - nums[i]数的下标x

下标j从0到x的这些数,均可做最小值,i到j之间的数,求组合数即可,又已知相同底数的所有组合数相加 = 2的底数次方

然后j从0到x再用等比数列前n项和公式即可

小于等于target / 2的,

下标j从0到i - 1均可做最小值

求法同上

class Solution {
public:
    int mod = 1e9 + 7;
    int q_pow(long long a, long long b)
    {
        int ret = 1;
        while(b)
        {
            if(b & 1) ret = ret * a % mod;
            a = (long long)a * a % mod;
            b >>= 1;
        }
        return ret;
    }
    int numSubseq(vector<int>& nums, int target) {
        int ret = 0;
        sort(nums.begin(), nums.end());
        ret = (upper_bound(nums.begin(), nums.end(), target / 2) - nums.begin()) % mod;
        int n = nums.size();
        for(int i = n - 1; i >= 0; i--)
        {
            if(nums[i] > target / 2)
            {
                int k = target - nums[i];
                int x = upper_bound(nums.begin(), nums.end(), k) - nums.begin();

                ret = (ret + q_pow(2, i) - q_pow(2, i - x) % mod) % mod;
            }
            else
            {

                ret = (ret + q_pow(2, i) - 1 % mod) % mod;


            }
        }
        return ret;
    }
};
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
原文地址:https://www.cnblogs.com/WTSRUVF/p/15787779.html