Generate a sequence from first X natural numbers which adds up to S on raising 2 to the power of their lowest set bits
Given two integers X and S, the task is to construct a sequence of distinct integers from the range [1, X] such that the sum of value 2K is equal to S, where K is the position of the first set bit from the end ( 0-based indexing )of the binary representation of each element is S.
Examples:
Input: X = 3, S = 4
Output: 2 3 1
Explanation:
Summation of 2K for every element in the set is as follows:
For 2, it is 2^1 = 2.
For 3, it is 2^0 = 1.
For 1, it is 2^0 = 1.
Therefore, the required sum = 2 + 1 + 1 = 4, which is equal to S.Input: X = 1, S = 5
Output: -1
Approach: The problem can be solved using a Greedy Approach. Follow the steps below to solve the problem:
- Initialize a variable, say lowBit, to store the value of 2K for any number, where K is the position of the first set bit from the end of the binary representation of each element.
- Insert all values of lowBit for all the numbers in the range [1, X] in a vector of pairs V to pair the numbers along with their lowBit values. The value of lowBit(X) can be obtained by log2(N & -N) + 1.
- Sort the vector in the reverse order to get the maximum lowBit at first.
- Initialize an array, say ans[], to store the required set and an integer, say ansSum, to store the current summation of lowBit values.
- Traverse the vector V and perform the following steps:
- Check if (ansSum+v[i].first) <= S, then add the value of v[i].second to the array ans[] and update ansSum.
- If ansSum is equal to the given sum S, then break from the loop and print the resultant array ans[] as the result.
- If the ansSum is not found to be equal to S, then print “-1”.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to calculate the lowest // set bit of any number N int lowBit( int N) { return log2(N & -N) + 1; } // Function to generate the sequence // which adds up to sum on raising 2 // to the power of lowest set bit // of all integers from the sequence void find_set( int X, int sum) { // Stores the lowBit value vector<pair< int , int > > v; // Traverse through 1 to X and // insert all the lowBit value for ( int i = 1; i <= X; i++) { pair< int , int > aux; aux.first = lowBit(i); aux.second = i; v.push_back(aux); } // Sort vector in reverse manner sort(v.rbegin(), v.rend()); bool check = false ; // Store all our set values vector< int > ans; // Stores the current // summation of lowBit int ansSum = 0; // Traverse vector v for ( int i = 0; i < v.size(); i++) { // Check if ansSum+v[i].first // is at most sum if (ansSum + v[i].first <= sum) { // Add to the ansSum ansSum += v[i].first; ans.push_back(v[i].second); } // If ansSum is same as the sum, // then break from loop if (ansSum == sum) { check = true ; break ; } } // If check is false, no such // sequence can be obtained if (!check) { cout << "-1" ; return ; } // Otherwise, print the sequence for ( int i = 0; i < ans.size(); i++) { cout << ans[i] << " " ; } } // Driver Code int main() { int X = 3, S = 4; // Generate and print // the required sequence find_set(X, S); return 0; } |
Java
// Java program for the above approach import java.io.*; import java.util.*; // User defined Pair class class Pair { int x; int y; // Constructor public Pair( int x, int y) { this .x = x; this .y = y; } } // class to define user defined conparator class Compare { static void compare(Pair arr[], int n) { // Comparator to sort the pair according to second element Arrays.sort(arr, new Comparator<Pair>() { @Override public int compare(Pair p1, Pair p2) { return p1.x - p2.x; } }); } } // Driver class class GFG { // Function to calculate the lowest // set bit of any number N static int lowBit( int N) { return ( int )(Math.log(N & -N) / Math.log( 2 )) + 1 ; } // Function to generate the sequence // which adds up to sum on raising 2 // to the power of lowest set bit // of all integers from the sequence static void find_set( int X, int sum) { // Stores the lowBit value Pair v[] = new Pair[X]; // Traverse through 1 to X and // insert all the lowBit value for ( int i = 0 ; i < X; i++) { Pair aux = new Pair(lowBit(i + 1 ), i + 1 ); v[i] = aux; } // Sort vector in reverse manner Compare obj = new Compare(); obj.compare(v, X); int j = X - 1 ; for ( int i = 0 ; i < X / 2 ; i++) { Pair temp = v[i]; v[i] = v[j]; v[j] = temp; j--; } boolean check = false ; // Store all our set values Vector<Integer> ans = new Vector<Integer>(); // Stores the current // summation of lowBit int ansSum = 0 ; // Traverse vector v for ( int i = 0 ; i < X; i++) { // Check if ansSum+v[i].first // is at most sum if (ansSum + v[i].x <= sum) { // Add to the ansSum ansSum += v[i].x; ans.add(v[i].y); } // If ansSum is same as the sum, // then break from loop if (ansSum == sum) { check = true ; break ; } } // If check is false, no such // sequence can be obtained if (!check) { System.out.println( "-1" ); return ; } // Otherwise, print the sequence for ( int i = 0 ; i < ans.size(); i++) { System.out.print(ans.get(i) + " " ); } } // Driver code public static void main(String[] args) { int X = 3 , S = 4 ; // Generate and print // the required sequence find_set(X, S); } } // This code is contributed by divyeshrabadiya07 |
Python3
# Python3 program for the above approach from math import log2, ceil, floor # Function to calculate the lowest # set bit of any number N def lowBit(N): return log2(N & - N) + 1 # Function to generate the sequence # which adds up to sum on raising 2 # to the power of lowest set bit # of all integers from the sequence def find_set(X, sum ): # Stores the lowBit value v = [] # Traverse through 1 to X and # insert all the lowBit value for i in range ( 1 , X + 1 ): aux = [ 0 , 0 ] aux[ 0 ] = lowBit(i) aux[ 1 ] = i v.append(aux) # Sort vector in reverse manner v = sorted (v)[:: - 1 ] check = False # Store all our set values ans = [] # Stores the current # summation of lowBit ansSum = 0 # Traverse vector v for i in range ( len (v)): # Check if ansSum+v[i][0] # is at most sum if (ansSum + v[i][ 0 ] < = sum ): # Add to the ansSum ansSum + = v[i][ 0 ] ans.append(v[i][ 1 ]) # If ansSum is same as the sum, # then break from loop if (ansSum = = sum ): check = True break # If check is false, no such # sequence can be obtained if ( not check): print ( "-1" ) return # Otherwise, print the sequence for i in range ( len (ans)): print (ans[i], end = " " ) # Driver Code if __name__ = = '__main__' : X, S = 3 , 4 # Generate and pr # the required sequence find_set(X, S) # This code is contributed by mohit kumar 29 |
C#
// C# program for the above approach using System; using System.Collections.Generic; class GFG { // Function to calculate the lowest // set bit of any number N static int lowBit( int N) { return ( int )(Math.Log(N & -N, 2)) + 1; } // Function to generate the sequence // which adds up to sum on raising 2 // to the power of lowest set bit // of all integers from the sequence static void find_set( int X, int sum) { // Stores the lowBit value List<Tuple< int , int >> v = new List<Tuple< int , int >>(); // Traverse through 1 to X and // insert all the lowBit value for ( int i = 1; i <= X; i++) { Tuple< int , int > aux = new Tuple< int , int >(lowBit(i), i); v.Add(aux); } // Sort vector in reverse manner v.Sort(); v.Reverse(); bool check = false ; // Store all our set values List< int > ans = new List< int >(); // Stores the current // summation of lowBit int ansSum = 0; // Traverse vector v for ( int i = 0; i < v.Count; i++) { // Check if ansSum+v[i].first // is at most sum if (ansSum + v[i].Item1 <= sum) { // Add to the ansSum ansSum += v[i].Item1; ans.Add(v[i].Item2); } // If ansSum is same as the sum, // then break from loop if (ansSum == sum) { check = true ; break ; } } // If check is false, no such // sequence can be obtained if (!check) { Console.Write( "-1" ); return ; } // Otherwise, print the sequence for ( int i = 0; i < ans.Count; i++) { Console.Write(ans[i] + " " ); } } // Driver code static void Main() { int X = 3, S = 4; // Generate and print // the required sequence find_set(X, S); } } // This code is contributed by divyesh072019 |
Javascript
<script> // Javascript program for the above approach // Function to calculate the lowest // set bit of any number N function lowBit(N) { return Math.log2(N & -N) + 1; } // Function to generate the sequence // which adds up to sum on raising 2 // to the power of lowest set bit // of all integers from the sequence function find_set(X, sum) { // Stores the lowBit value let v = []; // Traverse through 1 to X and // insert all the lowBit value for (let i = 1; i <= X; i++) { let aux = []; aux[0] = lowBit(i); aux[1] = i; v.push(aux); } // Sort vector in reverse manner v.sort((a, b) => a[0] - b[0]).reverse(); let check = false ; // Store all our set values let ans = []; // Stores the current // summation of lowBit let ansSum = 0; // Traverse vector v for (let i = 0; i < v.length; i++) { // Check if ansSum+v[i][0] // is at most sum if (ansSum + v[i][0] <= sum) { // Add to the ansSum ansSum += v[i][0]; ans.push(v[i][1]); } // If ansSum is same as the sum, // then break from loop if (ansSum == sum) { check = true ; break ; } } // If check is false, no such // sequence can be obtained if (!check) { document.write( "-1" ); return ; } // Otherwise, print the sequence for (let i = 0; i < ans.length; i++) { document.write(ans[i] + " " ); } } // Driver Code let X = 3, S = 4; // Generate and print // the required sequence find_set(X, S); // This code is contributed by _saurabh_jaiswal </script> |
2 3 1
Time Complexity: O(X Log X) because we need to calculate the lowest set bit for all integers from 1 to X, and sorting the vector of pairs takes O(X log X) time.
Auxiliary Space: O(X)
Please Login to comment...