Count number of distinct sum subsets within given range
Last Updated :
07 Mar, 2023
Given a set S of N numbers and a range specified by two numbers L (Lower Bound) and R (Upper Bound). Find the number of distinct values of all possible sums of some subset of S that lie between the given range. Examples :
Input : S = { 1, 2, 2, 3, 5 }, L = 1 and R = 5
Output : 5
Explanation : Every number between
1 and 5 can be made out using some subset of S.
{1 as 1, 2 as 2, 3 as 3, 4 as 2 + 2 and 5 as 5}
Input : S = { 2, 3, 5 }, L = 1 and R = 7
Output : 4
Explanation : Only 4 numbers between
1 and 7 can be made out, i.e. {2, 3, 5, 7}.
3 numbers which are {1, 4, 6} can't be made out in any way.
Prerequisites : Bitset | Bit Manipulation
Method 1(Simple) : A naive approach is to generate all possible subsets of given set, calculate their sum subset wise and push them into a hashmap. Iterate over the complete given range and count the numbers which exists in the hashmap. Method 2(Efficient) : An efficient way to solve this problem is by using bitset of size 105. Update the bitset for every element X by left shifting the bitset and doing bitwise OR with previous bitset so that the bitset at the new possible sums become 1. Then by using the concept of Prefix Sums, precompute the required count of numbers between 1 and i for prefix[1..i] to answer each query in O(1) if there are more than query being asked simultaneously. For a query L and R, answer would be simply prefix[R] - prefix[L - 1]
For e.g. S = { 2, 3, 5 }, L = 1 and R = 7 Considering a bitset of size 32 for simplicity. Initially 1 is at 0th position of bitset 00000000000000000000000000000001 For incoming 2, left shifting the bitset by 2 and doing OR with previous bitset 00000000000000000000000000000101 Similarly for 3, 00000000000000000000000000101101 for 5, 00000000000000000000010110101101 This final bitset contains 1 at those positions(possible sums) which can be made out using some subset of S. Hence between position 1 and 7, there are 4 set bits, thus the required answer.
Steps to solve the problem:
- Initialize a bitset BS of size SZ, where SZ is a large enough constant. Initialize the 0th position of the bitset to 1.
- Iterate over the elements S[i] of S from 0 to N-1.
- Left shift the bitset BS by S[i] positions and take the bitwise OR with the previous bitset BS.
- Initialize an array prefix of size SZ, and initialize all elements to 0.
- Iterate over the elements of prefix from 1 to SZ-1.
- Set prefix[i] = prefix[i-1] + BS[i].
- Calculate the answer as prefix[R] - prefix[L-1].
- Return the answer.
Below is the implementation of above approach in C++ :
CPP
// CPP Program to count the number
// distinct values of sum of some
// subset in a range
#include <bits/stdc++.h>
using namespace std;
// Constant size for bitset
#define SZ 100001
int countOfpossibleNumbers(int S[], int N,
int L, int R)
{
// Creating a bitset of size SZ
bitset <SZ> BS;
// Set 0th position to 1
BS[0] = 1;
// Build the bitset
for (int i = 0; i < N; i++) {
// Left shift the bitset for each
// element and taking bitwise OR
// with previous bitset
BS = BS | (BS << S[i]);
}
int prefix[SZ];
// Initializing the prefix array to zero
memset(prefix, 0, sizeof(prefix));
// Build the prefix array
for (int i = 1; i < SZ; i++) {
prefix[i] = prefix[i - 1] + BS[i];
}
// Answer the given query
int ans = prefix[R] - prefix[L - 1];
return ans;
}
// Driver Code to test above functions
int main()
{
int S[] = { 1, 2, 3, 5, 7 };
int N = sizeof(S) / sizeof(S[0]);
int L = 1, R = 18;
cout << countOfpossibleNumbers(S, N, L, R);
return 0;
}
Java
// Java Program to count the number
// distinct values of sum of some
// subset in a range
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG
{
// Constant size for bitset
static int SZ = 100001;
static int countOfpossibleNumbers(int[] S, int N, int L,
int R)
{
// Initially BS is 1
int BS = 1;
for (int i = 0; i < N; i++) {
// Left shift the bitset for each
// element and taking bitwise OR
// with previous bitset
BS = BS | (BS << S[i]);
}
// Convert BS to bitset array
String BS_ = Integer.toBinaryString(BS);
BS_ = String.format("%" + (-SZ) + "s", BS_).replace(' ', '0');
// Initializing the prefix array to zero
int[] prefix = new int[SZ];
for (int i = 0; i < SZ; i++)
prefix[i] = 0;
// Build the prefix array
for (var i = 1; i < SZ; i++) {
prefix[i]
= prefix[i - 1] + ((BS_.charAt(i) == '1') ? 1 : 0);
}
// Answer the given query
int ans = prefix[R] - prefix[L - 1];
return ans;
}
// Driver Code to test above functions
public static void main(String[] args)
{
int[] S = { 1, 2, 3, 5, 7 };
int N = S.length;
int L = 1;
int R = 18;
// Function call
System.out.println(countOfpossibleNumbers(S, N, L, R));
}
}
// This code is contributed by phasing17
Python3
# Python3 Program to count the number
# distinct values of sum of some
# subset in a range
# Constant size for bitset
SZ = 100001
def countOfpossibleNumbers(S, N, L, R):
# Initially BS is 1
BS = 1
for i in range(N):
# Left shift the bitset for each
# element and taking bitwise OR
# with previous bitset
BS = BS | (BS << S[i])
# Convert BS to bitset array
BS = bin(BS)[2::]
BS = [int(i) for i in BS.zfill(SZ)][::-1]
# Initializing the prefix array to zero
prefix = [0 for i in range(SZ)]
# Build the prefix array
for i in range(1, SZ):
prefix[i] = prefix[i - 1] + BS[i]
# Answer the given query
ans = prefix[R] - prefix[L - 1]
return ans
# Driver Code to test above functions
S = [1, 2, 3, 5, 7]
N = len(S)
L, R = 1, 18
print(countOfpossibleNumbers(S, N, L, R))
# This code is contributed by phasing17
C#
// C# Program to count the number
// distinct values of sum of some
// subset in a range
using System;
class GFG
{
// Constant size for bitset
static int SZ = 100001;
static int countOfpossibleNumbers(int[] S, int N, int L,
int R)
{
// Initially BS is 1
int BS = 1;
for (int i = 0; i < N; i++) {
// Left shift the bitset for each
// element and taking bitwise OR
// with previous bitset
BS = BS | (BS << S[i]);
}
// Convert BS to bitset array
string BS_ = Convert.ToString(BS, 2);
BS_ = BS_.PadRight(SZ, '0');
// Initializing the prefix array to zero
int[] prefix = new int[SZ];
for (int i = 0; i < SZ; i++)
prefix[i] = 0;
// Build the prefix array
for (var i = 1; i < SZ; i++) {
prefix[i]
= prefix[i - 1] + ((BS_[i] == '1') ? 1 : 0);
}
// Answer the given query
int ans = prefix[R] - prefix[L - 1];
return ans;
}
// Driver Code to test above functions
public static void Main(string[] args)
{
int[] S = { 1, 2, 3, 5, 7 };
int N = S.Length;
int L = 1;
int R = 18;
// Function call
Console.WriteLine(
countOfpossibleNumbers(S, N, L, R));
}
}
// This code is contributed by phasing17
JavaScript
// JS Program to count the number
// distinct values of sum of some
// subset in a range
// Constant size for bitset
const SZ = 100001;
function countOfpossibleNumbers(S, N, L, R)
{
//Initially BS is 1
var BS = 1;
for (var i = 0; i < N; i++) {
// Left shift the bitset for each
// element and taking bitwise OR
// with previous bitset
BS = BS | (BS << S[i]);
}
//Convert BS to bitset array
BS = BS.toString(2);
BS = BS.padEnd(SZ, "0");
BS = BS.split("");
BS = BS.map(str => {
return Number(str);
});
// Initializing the prefix array to zero
var prefix = new Array(SZ).fill(0);
// Build the prefix array
for (var i = 1; i < SZ; i++) {
prefix[i] = prefix[i - 1] + BS[i];
}
// Answer the given query
var ans = prefix[R] - prefix[L - 1];
return ans;
}
// Driver Code to test above functions
var S = [ 1, 2, 3, 5, 7 ];
var N = S.length;
var L = 1;
var R = 18;
console.log(countOfpossibleNumbers(S, N, L, R));
// This code is contributed by phasing17
Time Complexity: O(S*Z) where S*Z is the maximum sum for given constraints, i.e. 105
Similar Reads
Find the count of distinct numbers in a range
Given an array of size N containing numbers only from 0 to 63, and you are asked Q queries regarding it.Queries are as follows: 1 X Y i.e Change the element at index X to Y2 L R i.e Print the count of distinct elements present in between L and R inclusive Examples: Input: N = 7 ar = {1, 2, 1, 3, 1,
15 min read
2 Sum - Count distinct pairs with given sum
Given an array arr[] of size n and an integer target, the task is to count the number of distinct pairs in the array whose sum is equal to target.Examples:Input: arr[] = { 5, 6, 5, 7, 7, 8 }, target = 13 Output: 2 Explanation: Distinct pairs with sum equal to 13 are (5, 8) and (6, 7). Input: arr[] =
15 min read
Print combinations of distinct numbers which add up to give sum N
Given a positive integer N, the task is to find out all the combinations of positive integers that add upto the given integer N. The program should print only combinations, not permutations and all the integers in a combination must be distinct. For example, for input 3, either 1, 2 or 2, 1 should b
8 min read
Count of distinct integers in range [1, N] that do not have any subset sum as K
Given two positive integers N and K such that K?N, the task is to find the maximum number of distinct integers in the range [1, N] having no subset with a sum equal to K. If there are multiple solutions, print any. Examples: Input: N = 5, K = 3Output: 1 4 5Explanation: There are two sets of distinct
6 min read
Count of Subsets with given Difference
Given an array arr[] of size N and a given difference diff, the task is to count the number of partitions that we can perform such that the difference between the sum of the two subsets is equal to the given difference.Note: A partition in the array means dividing an array into two parts say S1 and
15+ min read
Number of subsets with sum divisible by M | Set 2
Given an array arr[] of N integers and an integer M, the task is to find the number of non-empty subsequences such that the sum of the subsequence is divisible by M. Examples: Input: arr[] = {1, 2, 3}, M = 1 Output: 7 Number of non-empty subsets of this array are 7. Since m = 1, m will divide all th
15+ min read
Count of distinct sums formed by N numbers taken from range [L, R]
Given three integers N, L, and R. The task is to count distinct sums formed by using N numbers from the range [L, R], where any number can be taken infinite times. Examples: Input: N = 2, L = 1, R = 3Output: 5Explanation: Generating all distinct combinations of 2 numbers taken from the range [1, 3]{
5 min read
Count subsets having distinct even numbers
Given a sequence of n numbers. The task is to count all the subsets of the given set which only have even numbers and all are distinct. Note: By the property of sets, if two subsets have the same set of elements then they are considered as one. For example: [2, 4, 8] and [4, 2, 8] are considered to
5 min read
Count of Subsequences with distinct elements
Given an array arr[] (1<=a[i]<=1e9) containing N (1<=N<=1e5) elements, the task is to find the total number of subsequences such that all elements in that subsequences are distinct. Since the answer can be very large print and modulo 1e9+7. Examples: Input: arr[] = [1, 1, 2, 2]Output: 8E
5 min read
Count of numbers in the range [L, R] which satisfy the given conditions
Given a range [L, R], the task is to find the count of numbers from this range that satisfy the below conditions: All the digit in the number are distinct.All the digits are less than or equal to 5. Examples: Input: L = 4, R = 13 Output: 5 4, 5, 10, 12 and 13 are the only valid numbers in the range
15+ min read