二进制1的个数

给定一个整数x(x >= 1 && x <= 2000000000),求1到x中所有整数二进制表示中1的总数。

比如x= 5
1的二进制表示为1
2的二进制表示为10
3的二进制表示为11
4的二进制表示为100
5的二进制表示为101
所以1的总数为7

对于这么大的数据,将所有结果打表保存,内存吃不消,打表的时间也要很久。
我们换个思路,做一张特殊的表sum[33], sum[x]代表:1到2^x - 1内所有1的总数。
求sum的时候我们可以得到一个递推关系:
1)当最高位为0的时候,得到sum1 = sum[x - 1]
2)当最高位为1的时候,得到sum2 = sum[x - 1] + 2 ^ (x - 1)
sum[x] = sum1 + sum2 = sum[x - 1] + sum[x - 1] + 2 ^ (x - 1)

我们用函数f(x)代表1到x中所有整数二进制表示中1的总数。
我们会得到另一个递推关系:
bitSum为x的二进制位数,比如5(101) =》bitSum = 3
1)当最高位为0的时候,得到sum1 = sum[bitSum - 1]
2)当最高位为1的时候,得到sum2 = 1到((1 << (sumOfBit - 1)) ^ x)中所有整数二进制表示中1的总数 + 最高位统计次数
sum2 = f((1 << (sumOfBit - 1)) ^ x) + ((1 << (sumOfBit - 1)) ^ n) + 1

f(x) = sum1 + sum2 = sum[bitSum - 1] + f((1 << (sumOfBit - 1)) ^ x) + ((1 << (sumOfBit - 1)) ^ n) + 1

效率为log2(x)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值