Minimum number of elements having sum S and bitwise OR as X
Last Updated :
21 Sep, 2022
Given two integers X and S, the task is to find the minimum length of the sequence of positive integers such that the sum of their elements is S and the bitwise OR(^) of their elements is X. If there does not exist any sequence which satisfies the above conditions, print ?1.
Examples:
Input: X = 13, S = 23
Output: 3
?Explanation: One of the valid sequence of length 3 is [9, 9, 5]
such that 9+9+5 =23 and 9^9^5 = 13.
Another valid sequence is {13, 9, 1}
It can be shown that there is no valid array with length < 3 .
Input: X = 6, S = 13
Output: -1
Approach: The problem can be solved based on the following observation:
Observations:
- X is one of the elements of the sequence: Considering the binary representation of X, we want to find a sequence of integers A of length N such that:
- If the ith bit of X is 0, the ith bit of Ai is 0 for all 1 ? i ? N.
- If the ith bit of X is 1, the ith bit of Ai is 1 for at least one 1 ? i ? N.
- We know that the sum of elements S ? X. To fulfill the second condition, we can simply have X as one of the elements of the sequence.
- Binary Search over the length of sequence: Suppose that a length N satisfies the given conditions:
- We can simply add a 0 to the previous sequence of length N. Thus, length (N+1) would also satisfy all conditions.
- We cannot say for sure if we can generate a sequence of length (N?1) satisfying all conditions based on the given result of length N. Thus, we would have to check again.
- We can apply binary search on the length of the sequence. If the current length m satisfies all conditions, we look for a smaller value of length, else, we look for a greater value of length.
- If no possible m exists between lower and upper bound, the answer is ?1.
- Check function of binary search: We need to determine if a sequence of length m can have sum of elements equal to S and bitwise or of elements equal to X.
- If we are given a length m, each (set) bit can have m copies. Since one of the elements is X, we have m?1 copies left for each set bit.
- Our problem reduces to finding a sequence of length (m?1) with sum (S?X) and bitwise or equal to (Y?X=X)
- We traverse the bits of X from highest bit to lowest bit (not including the lowest bit). Consider the ith bit:
- ith bit of X is 0: There should be no copies of set bits for the ith bit in (S?X).
- ith bit of X is 1: There can be at most (m?1) copies of set bits for the ith bit in (S?X). All excess copies can be transferred to the (i+1)th bit of (S?X) (by multiplying with a factor of 2).
- For the lowest bit:
- Lowest bit of X is 0: If there are any copies of set bits for the lowest bit in (S?X), sequence of length m does not exist, else it exists.
- Lowest bit of X is 1: If the number of copies of set bits for the lowest bit in (S?X) exceeds (m?1), sequence of length m does not exist, else it exists.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool possible( int x, int s, int m)
{
if (s < 0 || x < 0 || m < 0)
{
return false ;
}
for ( int i = 30; i >= 0 && s > 0; i--)
{
if (((x >> i) & 1) == 1)
{
int temp = s / (1 << i);
temp = temp < m ? temp : m;
s -= temp * (1 << i);
}
}
return (s == 0);
}
int minLength( int x, int s)
{
int foul = s + 1;
int left = 0, right = s + 1, m;
s = s - x;
while (left < right)
{
m = (left + (right - left) / 2);
bool val = possible(x, s, m - 1);
if (val)
{
right = m;
}
else
{
left = m + 1;
}
}
int ret = left < foul ? left : -1;
return ret;
}
int main()
{
int X = 13;
int S = 23;
cout << (minLength(X, S));
return 0;
}
|
Java
import java.io.*;
import java.util.*;
public class GFG {
public static boolean possible( int x, int s, int m)
{
if (s < 0 || x < 0 || m < 0 ) {
return false ;
}
for ( int i = 30 ; i >= 0 && s > 0 ; i--) {
if (((x >> i) & 1 ) == 1 ) {
int temp = s / ( 1 << i);
temp = temp < m ? temp : m;
s -= temp * ( 1 << i);
}
}
return (s == 0 );
}
public static int minLength( int x, int s)
{
int foul = s + 1 ;
int left = 0 , right = s + 1 , m;
s = s - x;
while (left < right) {
m = (left + (right - left) / 2 );
boolean val = possible(x, s, m - 1 );
if (val) {
right = m;
}
else {
left = m + 1 ;
}
}
int ret = left < foul ? left : - 1 ;
return ret;
}
public static void main(String[] args)
{
int X = 13 ;
int S = 23 ;
System.out.println(minLength(X, S));
}
}
|
Python3
def possible(x, s, m):
if (s < 0 or x < 0 or m < 0 ):
return False
i = 30
while (i > = 0 ):
if (((x >> i) & 1 ) = = 1 ):
temp = s / / ( 1 << i)
temp = temp if (temp < m) else m
s - = temp * ( 1 << i)
if s < = 0 :
break
i - = 1
return True if (s = = 0 ) else False
def minLength(x, s):
foul = s + 1
left = 0
right = s + 1
m = 0
s = s - x
while (left < right):
m = (left + (right - left) / / 2 )
val = possible(x, s, m - 1 )
if (val = = True ):
right = m
else :
left = m + 1
ret = left if (left < foul) else - 1
return ret
if __name__ = = "__main__" :
X = 13
S = 23
print (minLength(X, S))
|
C#
using System;
class GFG
{
public static bool possible( int x, int s, int m)
{
if (s < 0 || x < 0 || m < 0) {
return false ;
}
for ( int i = 30; i >= 0 && s > 0; i--) {
if (((x >> i) & 1) == 1) {
int temp = s / (1 << i);
temp = temp < m ? temp : m;
s -= temp * (1 << i);
}
}
return (s == 0);
}
public static int minLength( int x, int s)
{
int foul = s + 1;
int left = 0, right = s + 1, m;
s = s - x;
while (left < right) {
m = (left + (right - left) / 2);
bool val = possible(x, s, m - 1);
if (val) {
right = m;
}
else {
left = m + 1;
}
}
int ret = left < foul ? left : -1;
return ret;
}
public static void Main()
{
int X = 13;
int S = 23;
Console.Write(minLength(X, S));
}
}
|
Javascript
<script>
function possible(x, s, m)
{
if (s < 0 || x < 0 || m < 0) {
return false ;
}
for (let i = 30; i >= 0 && s > 0; i--) {
if (((x >> i) & 1) == 1) {
let temp = Math.floor(s / (1 << i));
temp = temp < m ? temp : m;
s -= temp * (1 << i);
}
}
return (s == 0);
}
function minLength(x, s)
{
let foul = s + 1;
let left = 0, right = s + 1, m;
s = s - x;
while (left < right) {
m = (left + Math.floor((right - left) / 2));
let val = possible(x, s, m - 1);
if (val) {
right = m;
}
else {
left = m + 1;
}
}
let ret = left < foul ? left : -1;
return ret;
}
let X = 13;
let S = 23;
document.write(minLength(X, S));
</script>
|
Output
3
Time Complexity: O(logS * logX) = O(log (S+X))
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...