一、题目
1、题目描述
给你一个整数
k
和一个整数x
。整数num
的价值是它的二进制表示中在x
,2x
,3x
等位置处设置位
的数目(从最低有效位开始)。下面的表格包含了如何计算价值的例子。
x num Binary Representation Price 1 13 000001101 3 2 13 000001101 1 2 233 011101001 3 3 13 000001101 1 3 362 101101010 2
num
的 累加价值 是从1
到num
的数字的 总 价值。如果num
的累加价值小于或等于k
则被认为是 廉价 的。请你返回 最大 的廉价数字。
2、接口描述
python3
class Solution:
def findMaximumNumber(self, k: int, x: int) -> int:
cpp
class Solution {
public:
long long findMaximumNumber(long long k, int x) {
}
};
C#
public class Solution {
public long FindMaximumNumber(long k, int x) {
}
}
3、原题链接
二、解题报告
1、思路分析
计算区间内所有数字的价值我们可以用数位dp计算,从而我们二分右端点即可
但是也有数学做法
给定x,[1, x]内有多少数字第0位为1? (x + 1) / 2
[1, x]内有多少数字第i位为1?
如果x >> i为奇数,那么有 (x >> i) / 2 * 2 + (x & ((1 << i )- 1)) + 1
如果x >> i为偶数,那么有 (x >> i) / 2 * 2
为什么?
和我们考虑第0位一样,就相当于向右移i位后,看第0位的1的个数,然后低i位有1 << i种情况,累计贡献
对于x >> i奇数的情况其实就是x 在第 i 位为1,然后此时低i位的选择取决于x的低i位
2、复杂度
时间复杂度:O(log^2 k / x) 空间复杂度:O(1)
3、代码详解
python3
class Solution:
def findMaximumNumber(self, k: int, x: int) -> int:
def f(num: int) -> int:
res = 0
i = x - 1
n = num >> i
while n:
res += (n // 2) << i
if n & 1:
msk = (1 << i) - 1
res += (num & msk) + 1
i += x
n >>= x
return res
return bisect_left(range((k + 1) << x), k + 1, key=f) - 1
cpp
using i64 = long long;
class Solution {
public:
long long findMaximumNumber(long long k, int x) {
auto f = [&](i64 num) -> i64 {
i64 res = 0;
int i = x - 1;
for (i64 n = num >> i; n; n >>= x, i += x) {
res += (n / 2LL) << i;
if (n & 1) {
i64 msk = (1LL << i) - 1;
res += (num & msk) + 1;
}
}
return res;
};
i64 lo = 0, hi = (k + 1) << x;
while (lo + 1 < hi) {
i64 m = (lo + hi) >> 1;
if (f(m) <= k) lo = m;
else hi = m;
}
return lo;
}
};
C#
public class Solution {
public long FindMaximumNumber(long k, int x) {
long lo = 0, hi = (k + 1) << x;
while (lo + 1 < hi) {
long m = (hi + lo) / 2L;
if (f(m) <= k) lo = m;
else hi = m;
}
return lo;
long f(long num) {
long res = 0;
int i = x - 1;
for (long n = num >> i; n > 0; n >>= x, i += x) {
res += (n / 2) << i;
if (n % 2 == 1) {
long msk = (1L << i) - 1;
res += (num & msk) + 1;
}
}
return res;
}
}
}