我的任务是计算1位间隔的数量[1,10 ^ 16]。对于这种情况,循环显然是无法使用的,我听说存在一种算法。有人可以帮忙吗?
更一般地说,区间[1,n]中1位数的算法会很好。
如果有帮助,我认为1位间隔[1,2 ^ n-1],n正整数的数量是n * 2 ^(n-1)。
答案 0 :(得分:0)
区间[1,n]中的1位数是区间[1,2 ^ m]中的1位数加上区间[1,n-2 ^ m]中的1位数再加上n - 2 ^ m。
m是⌊log(n)/log2⌋。
答案 1 :(得分:0)
设x = 2 ^ k + b,f(1,x)= f(0,x)= f(0,2 ^ k + b)= f(0,2 ^ k - 1) + f(2 ^ k,2 ^ k + b)
关键问题是f(2 ^ k,2 ^ k + b)
2 ^ k = 1 0 0 0 ... 0 0
2 ^ k + 1 = 1 0 0 0 ... 0 1
2 ^ k + 2 = 1 0 0 0 ... 1 0
2 ^ k + 3 = 1 0 0 0 ... 0 1
......
2 ^ k + b = 1 0 0 0 ...? ?
显然,从2 ^ k到2 ^ k + b的每个数字的第一位中有1位。并且存在从2 ^ k到2 ^ k + b的(b + 1)个整数。
我们可以删除第一个1位。它变得低于。
0 = 0 0 0 0 ... 0 0
1 = 0 0 0 0 ... 0 1
2 = 0 0 0 0 ... 1 0
3 = 0 0 0 0 ... 0 1
......
b = 0 0 0 0 ...? ?
所以,f(2 ^ k,2 ^ k + b)=(b + 1)+ f(0,b)。
f(0,x)= f(0,2 ^ k - 1)+ f(2 ^ k,2 ^ k + b) = f(0,2 ^ k - 1)+(b + 1)+ f(0,b)
显然,我们必须递归计算f(0,b)。
举一个第4步的例子。
对于f(1,31)= 80,并且31具有5个1位。
所以f(1,30)= 80 - 5 = 75;
让我们使用步骤4的方法计算f(1,30)。
f(1,30)= f(0,30)
= f(0,15)+ f(16,30)
= 32 + 15 + f(0,14)
= 47 + f(0,14)
= 47 + f(0,7)+ f(8,14)
= 47 + 12 + 7 + f(0,6)
= 66 + f(0,6)
= 66 + f(0,3)+ f(4,6)
= 66 + 4 + 3 + f(0,2)
= 73 + f(0,2)
= 73 + f(0,1)+ f(2,2)
= 74 + f(2,2)
= 74 + 1 + f(0,0)
= 75