📌  相关文章
📜  小数点和,即前N个自然数的二进制表示形式

📅  最后修改于: 2021-04-17 14:28:52             🧑  作者: Mango

给定正整数N ,任务是计算所有小数的总和,这些总和可以表示为前N个自然数的二进制表示形式。

例子:

天真的方法:解决问题的最简单方法是在[1,N]范围内迭代一个循环,并在每次迭代中将当前数字转换为其二进制表示形式并将其添加到总和中。将所有数字相加后,将其总和作为结果打印。

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

高效方法:还可以通过找到与N的最高有效位(MSB)位置不同的数字的贡献,然后通过MSB找出其余数字的贡献,来优化上述方法。请按照以下步骤解决问题:

  • 初始化一个变量,将ans设为0,以将所有数字之和存储在前N个自然数的二进制表示形式中。
  • 迭代直到N的值至少为0 ,然后执行以下步骤:
    • 将数字N的MSB位置存储在变量X中,并存储值2 (X – 1) 在变量中说A。
    • 初始化一个变量,例如cur0,以存储与N不在同一MSB位置的数字的贡献。
    • 迭代范围[1,X] ,在每次迭代中,将A添加到变量cur中,然后将A乘以10
    • 完成上述步骤后,将cur的值添加到ans并将剩余的元素存储在变量rem中(N – 2 X +1)
    • 通过将(rem * 10 X )加到ans上,再加上MSB对其余数字的贡献。
    • 在下一次迭代中将N的值更新为(rem – 1)。
  • 完成上述步骤后,输出ans的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
const int MOD = 1e9 + 7;
 
// Function to find the sum of first
// N natural numbers represented
// in binary representation
void sumOfBinaryNumbers(int n)
{
    // Stores the resultant sum
    int ans = 0;
 
    int one = 1;
 
    // Iterate until the value of
    // N is greater than 0
    while (1) {
 
        // If N is less than 2
        if (n <= 1) {
            ans = (ans + n) % MOD;
            break;
        }
 
        // Store the MSB position of N
        int x = log2(n);
 
        int cur = 0;
        int add = (one << (x - 1));
 
        // Iterate in the range [1, x]
        // and add the contribution of
        // the  numbers from 1 to (2^x-1)
        for (int i = 1; i <= x; i++) {
 
            // Update the value of the
            // cur and add
            cur = (cur + add) % MOD;
            add = (add * 10 % MOD);
        }
 
        // Add the cur to ans
        ans = (ans + cur) % MOD;
 
        // Store the remaining numbers
        int rem = n - (one << x) + 1;
 
        // Add the contribution by MSB
        // by the remaining numbers
        int p = pow(10, x);
        p = (p * (rem % MOD)) % MOD;
        ans = (ans + p) % MOD;
 
        // The next iteration will
        // be repeated for 2^x - 1
        n = rem - 1;
    }
 
    // Print the result
    cout << ans;
}
 
// Driver Code
int main()
{
    int N = 3;
    sumOfBinaryNumbers(N);
 
    return 0;
}


Python3
# Python3 program for the above approach
from math import log2, pow
 
MOD = 1000000007
 
# Function to find the sum of first
# N natural numbers represented
# in binary representation
def sumOfBinaryNumbers(n):
     
    # Stores the resultant sum
    ans = 0
 
    one = 1
 
    # Iterate until the value of
    # N is greater than 0
    while (1):
         
        # If N is less than 2
        if (n <= 1):
            ans = (ans + n) % MOD
            break
 
        # Store the MSB position of N
        x = int(log2(n))
 
        cur = 0
        add = (one << (x - 1))
 
        # Iterate in the range [1, x]
        # and add the contribution of
        # the  numbers from 1 to (2^x-1)
        for i in range(1, x + 1, 1):
             
            # Update the value of the
            # cur and add
            cur = (cur + add) % MOD
            add = (add * 10 % MOD)
 
        # Add the cur to ans
        ans = (ans + cur) % MOD
 
        # Store the remaining numbers
        rem = n - (one << x) + 1
 
        # Add the contribution by MSB
        # by the remaining numbers
        p = pow(10, x)
        p = (p * (rem % MOD)) % MOD
        ans = (ans + p) % MOD
 
        # The next iteration will
        # be repeated for 2^x - 1
        n = rem - 1
 
    # Print the result
    print(int(ans))
 
# Driver Code
if __name__ == '__main__':
     
    N = 3
     
    sumOfBinaryNumbers(N)
 
# This code is contributed by SURENDRA_GANGWAR


C#
// C# program for the above approach
using System;
class GFG{
     
const int MOD = 1000000007;
 
// Function to find the sum of first
// N natural numbers represented
// in binary representation
static void sumOfBinaryNumbers(int n)
{
     
    // Stores the resultant sum
    int ans = 0;
 
    int one = 1;
 
    // Iterate until the value of
    // N is greater than 0
    while (true)
    {
         
        // If N is less than 2
        if (n <= 1)
        {
            ans = (ans + n) % MOD;
            break;
        }
 
        // Store the MSB position of N
        int x = (int)Math.Log(n, 2);
 
        int cur = 0;
        int add = (one << (x - 1));
 
        // Iterate in the range [1, x]
        // and add the contribution of
        // the  numbers from 1 to (2^x-1)
        for(int i = 1; i <= x; i++)
        {
             
            // Update the value of the
            // cur and add
            cur = (cur + add) % MOD;
            add = (add * 10 % MOD);
        }
 
        // Add the cur to ans
        ans = (ans + cur) % MOD;
 
        // Store the remaining numbers
        int rem = n - (one << x) + 1;
 
        // Add the contribution by MSB
        // by the remaining numbers
        int p = (int)Math.Pow(10, x);
        p = (p * (rem % MOD)) % MOD;
        ans = (ans + p) % MOD;
 
        // The next iteration will
        // be repeated for 2^x - 1
        n = rem - 1;
    }
 
    // Print the result
    Console.WriteLine(ans);
}
 
// Driver Code
public static void Main()
{
    int N = 3;
     
    sumOfBinaryNumbers(N);
}
}
 
// This code is contributed by ukasp


输出:
22

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