📜  前N个非负整数的连续位差之和

📅  最后修改于: 2021-05-06 20:55:17             🧑  作者: Mango

给定正整数N ,任务是找出从0到N的所有连续位差之和。
注意:如果两个(例如(3,4))的位长度不同,则在开头(011,100)后面附加0。
例子:

天真的方法:
最简单的方法是按位比较范围内的两个连续值,并找出这两个数字相差多少位。将此差值加到总和上。这样获得的最终总和是所需的解决方案。
时间复杂度: O(N)
方法:
为了优化上述解决方案,需要进行以下观察:

  • 连续的数字位差遵循一个模式,即每个等于(2 i )的值X与先前的数字以及(2 i – 1)数在X和(2 i之上)的位差为(i +1)。 – 1)X以下的数字遵循相同的模式。
  • 对于X = 4(2 2 ),i = 2的位差为(2 +1),数字(1、2、3)和(5、6、7)遵循相同的位差模式。
For X = 4, the pattern is as follows:
NUM   BIT Diff
1     1(0, 1)
2     2(1, 2)
3     1(2, 3)
4     3(3, 4)
5     1(4, 5)
6     2(5, 6)
7     1(6, 7)

请按照以下步骤解决问题:

  • 对于每个N ,找到小于或等于N的最接近的数字,即2的幂。假设该数字为M。
  • 对于所有小于M的数字,可以使用以下递归方法找出连续位差的总和。
  • 初始化大小为65(基于0的索引)的数组,以存储使用递归函数Count()时获得的值,以便将来,如果需要相同的Count()值,则可以直接获取它们而无需递归调用Count()函数以节省时间。
  • 使用以下公式,对大于M的剩余数重复相同的过程。

例如:
对于N = 10,使用Count(3)计算最接近的2的幂,即M = 8,然后对剩余的大于8的数重复该过程。
下面是上述方法的实现:

C++
// C++ program for the above problem
#include 
using namespace std;
 
long long a[65] = { 0 };
 
// Recursive function to count
// the sum of bit differences
// of numbers from 1 to
// pow(2, (i+1)) - 1
long long Count(int i)
{
    // base cases
    if (i == 0)
        return 1;
 
    else if (i < 0)
        return 0;
 
    // Recursion call if the sum
    // of bit difference of numbers
    // around i are not calculated
    if (a[i] == 0) {
        a[i] = (i + 1) + 2 * Count(i - 1);
        return a[i];
    }
 
    // return the sum of bit
    // differences if already
    // calculated
    else
        return a[i];
}
 
// Function to calculate the
// sum of bit differences up to N
long long solve(long long n)
{
    long long i, sum = 0;
 
    while (n > 0) {
 
        // nearest smaller power
        // of 2
        i = log2(n);
 
        // remaining numbers
        n = n - pow(2, i);
 
        // calculate the count
        // of bit diff
        sum = sum + (i + 1) + Count(i - 1);
    }
    return sum;
}
 
// Driver code
int main()
{
    long long n = 7;
    cout << solve(n) << endl;
    return 0;
}


Java
// Java program for the above problem
import java.util.*;
class GFG{
   
static int a[] = new int[65];
   
// Recursive function to count
// the sum of bit differences
// of numbers from 1 to
// pow(2, (i+1)) - 1
static int Count(int i)
{
     
    // base cases
    if (i == 0)
        return 1;
  
    else if (i < 0)
        return 0;
  
    // Recursion call if the sum
    // of bit difference of numbers
    // around i are not calculated
    if (a[i] == 0)
    {
        a[i] = (i + 1) + 2 * Count(i - 1);
        return a[i];
    }
  
    // return the sum of bit
    // differences if already
    // calculated
    else
        return a[i];
}
  
// Function to calculate the
// sum of bit differences up to N
static int solve(int n)
{
    int i, sum = 0;
  
    while (n > 0)
    {
  
        // nearest smaller power
        // of 2
        i = (int)(Math.log(n) / Math.log(2));
 
  
        // remaining numbers
        n = n - (int)Math.pow(2, i);
  
        // calculate the count
        // of bit diff
        sum = sum + (i + 1) + Count(i - 1);
    }
    return sum;
}
  
// Driver code
public static void main(String[] args)
{
    int  n = 7;
    System.out.println(solve(n));
}
}
 
// This code is contributed by rock_cool


Python3
# Python3 program for the above problem
import math
 
a = [0] * 65
 
# Recursive function to count
# the sum of bit differences
# of numbers from 1 to
# pow(2, (i+1)) - 1
def Count(i):
     
    # Base cases
    if (i == 0):
        return 1
 
    elif (i < 0):
        return 0
 
    # Recursion call if the sum
    # of bit difference of numbers
    # around i are not calculated
    if (a[i] == 0):
        a[i] = (i + 1) + 2 * Count(i - 1)
        return a[i]
 
    # Return the sum of bit
    # differences if already
    # calculated
    else:
        return a[i]
 
# Function to calculate the
# sum of bit differences up to N
def solve(n):
     
    sum = 0
 
    while (n > 0):
 
        # Nearest smaller power
        # of 2
        i = int(math.log2(n))
 
        # Remaining numbers
        n = n - pow(2, i)
 
        # Calculate the count
        # of bit diff
        sum = sum + (i + 1) + Count(i - 1)
     
    return sum
 
# Driver code
n = 7
 
print(solve(n))
 
# This code is contributed by sanjoy_62


C#
// C# program for the above problem
using System;
class GFG{
 
static int []a = new int[65];
 
// Recursive function to count
// the sum of bit differences
// of numbers from 1 to
// pow(2, (i+1)) - 1
static int Count(int i)
{
     
    // base cases
    if (i == 0)
        return 1;
 
    else if (i < 0)
        return 0;
 
    // Recursion call if the sum
    // of bit difference of numbers
    // around i are not calculated
    if (a[i] == 0)
    {
        a[i] = (i + 1) + 2 * Count(i - 1);
        return a[i];
    }
 
    // return the sum of bit
    // differences if already
    // calculated
    else
        return a[i];
}
 
// Function to calculate the
// sum of bit differences up to N
static int solve(int n)
{
    int i, sum = 0;
 
    while (n > 0)
    {
 
        // nearest smaller power
        // of 2
        i = (int)(Math.Log(n) / Math.Log(2));
 
 
        // remaining numbers
        n = n - (int)Math.Pow(2, i);
 
        // calculate the count
        // of bit diff
        sum = sum + (i + 1) + Count(i - 1);
    }
    return sum;
}
 
// Driver code
public static void Main(String[] args)
{
    int n = 7;
    Console.Write(solve(n));
}
}
 
// This code is contributed by shivanisinghss2110


Javascript


输出:
11

时间复杂度: O(log(N))
辅助空间: O(1)