
Given N = 3. The binary representation of 1, 2, and 3 are 1, 10, and 11, respectively. So, the string formed by concatenating the binary representation of 1, 2, and 3 is “11011”, whose decimal value is 27. Therefore, the secret code corresponding to N = 3 is 27.
The first line of input contains an integer 'T' representing the number of test cases.
The first and only line of each test case contains an integer ‘N’ to be decoded.
For each test case, print a single line containing a single integer denoting the decimal value of the binary string formed by concatenating the binary representations of 1 to ‘N’ in order. Since the decimal value can be very large, print the answer after modulo 1000000007.
The output of each test case will be printed in a separate line.
You do not need to print anything, it has already been taken care of. Just implement the given function.
1 <= T <= 5
1 <= N <= 3000
Where ‘T’ is the number of test cases and ‘N’ is the integer to be decoded.
Time limit: 1 sec.
The idea is to use the brute force approach.
For every integer in the range [1, N], we will find out its binary representation and concatenate them to create a string. Then, we will traverse the string and find its decimal value.
For a binary string, “11011100”, the decimal value is calculated as: (1 * 2 ^ 7) + (1 * 2 ^ 6) + (0 * 2 ^ 5) + (1 * 2 ^ 4) + (1 * 2 ^ 3) + (1 * 2 ^ 2) + (0 * 2 ^ 1) + (0 * 2 ^ 0) = 220.
Algorithm:
Description of ‘createBinaryString’ function
This function will take only one parameter:
void createBinaryString(N):
We do not need to create a whole concatenated string for all integers from 1 to ‘N’. If we look more closely, then the next integer’s binary representation causes a left shift to the binary representation of the previous integer by the length of the binary representation of the next integer.
For example: Suppose we want to decode the value for N = 4.
Then,
For N = 1, Binary Representation = 1 => String = “1”.
For N = 2, Binary Representation = 10 => String = “1” + “10” = “110”.
We can see that the previous string “1” has been left-shifted by 2, i.e., the length of “10”.
For N = 3, Binary Representation = 11 => String = “110” + “11” = “11011”.
Again, the previous string “110” has been left-shifted by 2, i.e., the length of “11”.
For N = 4, Binary Representation = 100 => String = “11011” + “100” = “11011100”.
Here, the previous string “11011” has been left-shifted by 3, i.e., the length of “100”.
With this observation, we can easily find the final decimal representation.
N String Result
1 “1” 1
2 “1 10” 1 << 2 + 2 = 6
3 “110 11” 6 << 2 + 3 = 27
4 “11011 100” 27 << 3 + 4 = 220
Therefore, the generalised formula will be “Result = Previous Result << Length of Current Binary Representation + Current Integer”.
Note: Any decimal number, ‘N’ has ‘log2(N) + 1’ digits in its binary representation.
Algorithm:
We can use bitwise operators to decrease the runtime of the logic mentioned in Approach 2.
Optimization 1:
Instead of using the ‘log’ operator to count the number of digits, we will use the fact that the length only increments when the integer is a power of 2. So, we will initialize ‘LENGTH’ with 0 and increment it only when for any integer, ‘i’ : (i & (i - 1)) == 0, i.e. ‘i’ has single bit 1.
Optimization 2:
Instead of using the ‘+’ operator to append the current integer, we can use bitwise OR ‘|’.
Algorithm: