📅  最后修改于: 2023-12-03 15:23:29.462000             🧑  作者: Mango
在二进制表示中,LSB(Least Significant Bit)指最低有效位,即最右边的位。本文介绍如何计算一个区间 [L, R] 中二进制表示中 LSB 为 0 的数字个数。
对于一个二进制数,如果它的 LSB 为 1,则将它减去 1 会使得它的 LSB 变成 0,并且更高位的数字都变成了反码(即 0 变成 1,1 变成 0)。例如,1011 - 1 = 1010,1100 - 1 = 1011。
根据这个规律,如果将一个数减去 1,并将它和原数做 &(按位与)运算,会把它的 LSB 以及所有比它更低的位都变成 0。例如,1011 & 1010 = 1010,1100 & 1011 = 1000。
因此,如果我们将一个数字 x 和它的 x - 1 做 & 运算,再统计有多少个数字 y 满足 y & (y-1) == 0,则 y 的二进制表示中 LSB 为 0。那么在区间 [L, R] 中满足条件的数字个数就是 f(R) - f(L-1),其中 f(x) 表示小于等于 x 的数字中,满足 y & (y-1) == 0 的数字个数。
def count_lsb_zero_numbers(L, R):
def count_lsb_zero(n):
cnt = 0
while n > 0:
n &= n - 1
cnt += 1
return cnt
def count_f(x):
res = 0
for i in range(1, 32):
res += x // (1 << i) * (1 << (i - 1))
res += max(0, (x % (1 << i)) - (1 << (i - 1)) + 1)
return res
return count_f(R) - count_f(L-1)
print(count_lsb_zero_numbers(3, 10)) # 输出 6,满足条件的数字为 4、5、6、8、9、10
以上是 Python 代码示例,实现了计算 [L, R] 区间中二进制表示中 LSB 为 0 的数字个数的函数。其中 count_lsb_zero
函数用于计算一个数的二进制表示中 1 的个数, count_f
函数用于计算小于等于 x 的数字中,满足 y & (y-1) == 0 的数字个数,最后将区间 [L, R] 分别代入 count_f 函数即可得到答案。