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; } };
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。