Given two integers L and R, the task is to find the count of the sets of a maximum size such that each element in the set is between L and R (inclusive), and for any two elements in the set one of them is divisible by the other.
Examples:
Input: L = 3, R = 19
Output: 4
Explanation: There will be 4 possible sets – {3, 6, 12}, {3, 6, 18}, {3, 9, 18}, {4, 8, 16}Input: L = 4, R = 8
Output: 1
Approach: This can be solved with the following idea:
- Let {S1, S2, S3…… Smx} be a set of maximum sizes satisfying the given conditions. Let Mi = Si+1/Si.
- It is intuitive that for Smx to be the minimum we need to choose S1 and Mi for all i as low as possible, the minimum value of S1 can be L and the minimum value of Mi can be 2.
- However, we can choose one of the Mi to be 3 so that Smx will be (3/2) times the initial value of Smx (which should be less than R), if we choose any value of Mi to be more than 3, the size of the set would not be maximum as there can always be a new element Smx+1 = 2*Smx such size of the set would become mx+1.
Follow the below steps to implement the idea:
- First calculate the value of mx, i.e the maximum possible size of the set. This can be calculated assuming all the values of Mi are 2, and the value of S1 is L, then mx = floor(log2(r/l)) + 1.
- Calculate the maximum value of S1 such that a set of size mx satisfying the given conditions is possible. Let’s call it X, We know 2mx-1 * X ≤ R, then X = R/2mx-1.
- Calculate the maximum value of S1 such that a set of size mx satisfying the given conditions is possible and one of the values of Mi can be 3 instead of 2, let us call it Y. We know that 3*2mx-2 * Y ≤ R, then Y = R/(3*2mx-2).
- We know L ≤ Y ≤ X ≤ R, a number of sets with S1 ≤ Y are (Y-L+1)*mx, note that we multiplied by mx as any of the Mi in these sets can be 3. A number of sets with S1>Y and S1 ≤ X is X – Y.
- Total sets of maximum size = (Y-L+1)*mx + X-Y.
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
int countSets( int L, int R)
{ // Calculating the maximum
// size of such sets
int mx = floor (log2(R / L)) + 1;
// If size is 1 then all any of the
// elements in the range can be
// selected to be in set
if (mx == 1) {
return (R - L + 1);
}
// Calculating X and Y
int X = R / pow (2, mx - 1);
int Y = R / ( pow (2, mx - 2) * 3);
// If Y is less than L then M[i]
// can never be 3 for any value of i
if (Y < L) {
return (X - L + 1);
}
// Calculating Answer
int ans = (Y - L + 1) * mx + (X - Y);
return ans;
} // Driver Code int main()
{ int L = 3, R = 19;
// Function Call
cout << countSets(L, R) << endl;
} |
import java.util.*;
public class Main {
static int countSets( int L, int R) {
// Calculating the maximum
// size of such sets
int mx = ( int ) Math.floor(Math.log(R / L) / Math.log( 2 )) + 1 ;
// If size is 1 then any of the
// elements in the range can be
// selected to be in set
if (mx == 1 ) {
return (R - L + 1 );
}
// Calculating X and Y
int X = ( int ) (R / Math.pow( 2 , mx - 1 ));
int Y = ( int ) (R / (Math.pow( 2 , mx - 2 ) * 3 ));
// If Y is less than L then M[i]
// can never be 3 for any value of i
if (Y < L) {
return (X - L + 1 );
}
// Calculating Answer
int ans = (Y - L + 1 ) * mx + (X - Y);
return ans;
}
// Driver Code
public static void main(String[] args) {
int L = 3 , R = 19 ;
// Function Call
System.out.println(countSets(L, R));
}
} // This code is contributed by Prajwal Kandekar |
import math
def countSets(L, R):
# Calculating the maximum
# size of such sets
mx = int (math.floor(math.log(R / L) / math.log( 2 ))) + 1
# If size is 1 then any of the
# elements in the range can be
# selected to be in set
if mx = = 1 :
return (R - L + 1 )
# Calculating X and Y
X = int (R / ( 2 * * (mx - 1 )))
Y = int (R / (( 2 * * (mx - 2 )) * 3 ))
# If Y is less than L then M[i]
# can never be 3 for any value of i
if Y < L:
return (X - L + 1 )
# Calculating Answer
ans = (Y - L + 1 ) * mx + (X - Y)
return ans
# Driver Code L = 3
R = 19
# Function Call print (countSets(L, R))
|
// C# code to implement the approach using System;
public class GFG {
static int countSets( int L, int R)
{
// Calculating the maximum size of such sets
int mx
= ( int )Math.Floor(Math.Log(R / L) / Math.Log(2))
+ 1;
// If size is 1 then any of the elements in the
// range can be selected to be in set
if (mx == 1) {
return (R - L + 1);
}
// Calculating X and Y
int X = ( int )(R / Math.Pow(2, mx - 1));
int Y = ( int )(R / (Math.Pow(2, mx - 2) * 3));
// If Y is less than L then M[i] can never be 3 for
// any value of i
if (Y < L) {
return (X - L + 1);
}
// Calculating Answer
int ans = (Y - L + 1) * mx + (X - Y);
return ans;
}
static public void Main()
{
// Code
int L = 3, R = 19;
// Function Call
Console.WriteLine(countSets(L, R));
}
} // This code is contributed by lokesh. |
function countSets(L, R) {
// Calculating the maximum
// size of such sets
let mx = Math.floor(Math.log2(R / L)) + 1;
// If size is 1 then all any of the
// elements in the range can be
// selected to be in set
if (mx === 1) {
return R - L + 1;
}
// Calculating X and Y
let X = Math.floor(R / Math.pow(2, mx - 1));
let Y = Math.floor(R / (Math.pow(2, mx - 2) * 3));
// If Y is less than L then M[i]
// can never be 3 for any value of i
if (Y < L) {
return X - L + 1;
}
// Calculating Answer
let ans = (Y - L + 1) * mx + (X - Y);
return ans;
} // Driver Code let L = 3, R = 19; // Function Call console.log(countSets(L, R)); |
4
Time Complexity: O(1)
Auxiliary Space: O(1)