基于位运算的F(x)计数问题:分析并修复高效实现代码
问题核心逻辑拆解与bug分析
原问题的数学化简(高效算法的基础)
首先把题目中的位运算条件和求和式转化为简洁的数学表达式:
- 约束条件化简:题目要求
(x | i) - (x & i) = x - i,利用位运算性质x|i - x&i = x^i(异或),等式可转化为x^i = x - i。进一步推导可得i = x & i,即i是x的二进制子集(i的所有1位都在x的1位中),此时0≤i≤x自然成立。 - 求和式化简:此时
F(x) = ∑(x - i),其中i遍历x的所有二进制子集。假设x的二进制有m个1位,子集总数为2^m:- 总和展开为
x*2^m - ∑i,其中∑i是所有子集的和,每个1位在子集中出现2^(m-1)次,因此∑i = x*2^(m-1) - 最终得到F(x) = x * 2^(m-1)(当x=0时,m=0,F(0)=0单独成立)
- 总和展开为
高效算法的核心思路
基于上述化简,算法的核心是枚举x中1的位数m,统计每个m对应的符合条件的x数量,最后累加:
- 枚举
m从1开始,直到2^(m-1) > K(此时x≥1时x*2^(m-1)≥2^(m-1) > K,无符合条件的x) - 对每个m,计算最大允许的x为
X = floor(K / 2^(m-1)),统计≤X且恰好有m个1位的数的数量(用组合数计算) - 加上x=0的情况(F(0)=0≤K,总是有效)
针对K=6的bug分析
正确的统计过程:
- x=0:计数+1
- m=1:
2^(1-1)=1,X=6//1=6,≤6且1个1位的数有1、2、4 → 计数+3 - m=2:
2^(2-1)=2,X=6//2=3,≤3且2个1位的数有3 → 计数+1 - m≥3:
2^(m-1)≥4,X=6//4=1,无法找到有3个1位的数 → 计数+0
总计数=1+3+1=5,与正确结果一致。
buggy代码输出3,最可能的原因是F(x)的表达式推导错误:
代码错误地将F(x)=x*2^(m-1)写成了F(x)=x*2^m,导致计算X时用了X = floor(K / 2^m):
- m=1:X=6//2=3,≤3且1个1位的数有1、2 → 计数+2
- m=2:X=6//4=1,无符合条件的数 → 计数+0
- 加上x=0的话总计数=1+2=3,正好匹配代码输出。
其他可能的辅助bug:
- 遗漏x=0的统计(但此时若表达式错误,总计数会是2,不匹配输出,所以不是主因)
- 组合数统计逻辑错误(比如计算≤X的m个1位的数时少算,但结合输出结果,表达式错误是最核心的问题)
内容的提问来源于stack exchange,提问作者Giogre
相关产品推荐
相关产品推荐

