Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 范围内的快速位计数_Algorithm_Bitcount - Fatal编程技术网

Algorithm 范围内的快速位计数

Algorithm 范围内的快速位计数,algorithm,bitcount,Algorithm,Bitcount,我需要找到解决这个问题的算法: 查找[x,y]范围内数字中所有正位的总和。 警告:x和y可能非常大(从1到10^20)。 感谢您的帮助。看一个具体的例子来识别模式可能会有所启发。例如,20到25岁。以下是它们的二进制表示: 20: 10100 21: 10101 22: 10110 23: 10111 24: 11000 25: 11001 按列查看,很明显,最右边的列总是在0和1之间交替。 由此我们可以得出结论,如果范围中有N个数字,且N为偶数,则最右边的列中有N/2位。 现在忽略最右边的列

我需要找到解决这个问题的算法:
查找[x,y]范围内数字中所有正位的总和。
警告:x和y可能非常大(从1到10^20)。

感谢您的帮助。

看一个具体的例子来识别模式可能会有所启发。例如,20到25岁。以下是它们的二进制表示:

20: 10100
21: 10101
22: 10110
23: 10111
24: 11000
25: 11001
按列查看,很明显,最右边的列总是在0和1之间交替。 由此我们可以得出结论,如果范围中有N个数字,且N为偶数,则最右边的列中有N/2位。 现在忽略最右边的列,并尝试在剩余的位中识别模式

1010
1010
1011
1011
1100
1100
列表中的每个数字只重复一次。 转换为十进制,我们看到这些数字是
1010=10
1011=11
1100=12
。 通过这两个观察,我们可以得出结论:
bitsInRange(20,25)=(27-20-1)+2*bitsInRange(10,12)
。对于任意偶数开始数和奇数结束数,我们确定的两种模式均为真,因此公式可推广为:

bitsInRange(X,Y) =
if X is even and Y is odd:
    (Y - X - 1) + 2*bitsInRange(X/2, (Y-1)/2)
但是如果我们有一个奇数的开始数,或者一个偶数的结束数呢?上述公式不适用于这些类型的数字,因为我们确定的两种模式对于这些类型的数字并不完全相同。你可以尝试为偶数和奇数的每一个可能的组合编写单独的公式,但这种方法是危险的,而且充满了风险。如果您充分利用这些关键特性,您将更轻松:

bitsInRange(X, Y) = bitsInRange(X, Y-1) + numBits(Y)
bitsInRange(X, Y) = bitsInRange(X+1, Y) + numBits(X)
。。。其中
numBits
给出单个数字中
1
位的数量

现在我们可以为偶数和奇数范围的每个可能组合编写一个递归公式。(顺便说一下,我们还需要一个基本案例)


因为最后一个案例将问题空间分成了一半,而所有其他案例都将问题快速转化为最后一个案例,所以整个公式具有对数复杂性。如果您试图获得像[1,10^20]这样的大范围的位,这是很好的。即使是这样的大数字,
bitsInRange
也只能运行大约200次。

提示:在最右边的位置找到“1”位的数量。这是家庭作业吗?你已经试过什么了?问题的哪一方面你被卡住了?可能是重复的我有一些野蛮版本的算法。我对每个元素使用uuu builtinpop_count(),并将其添加到sum变量中。这个问题相当于上所述的问题(我刚才回答:-)
function bitsInRange(X,Y):
    if X == Y:
        return numBits(X)
    if X is odd:
        return bitsInRange(X+1, Y) + numBits(X)
    if Y is even:
        return bitsInRange(X, Y-1) + numBits(Y)
    return (Y - X - 1) + 2*bitsInRange(X/2, (Y-1)/2)