 GeeksforGeeks App
Open App Browser
Continue

# Subset Sum Queries in a Range using Bitset

Given an array[] of N positive integers and M queries. Each query consists of two integers L and R represented by a range. For each query, find the count of numbers that lie in the given range which can be expressed as the sum of any subset of given array.

Prerequisite : Subset Sum Queries using Bitset

Examples:

Input : arr[] = { 1, 2, 2, 3, 5 }, M = 4 L = 1, R = 2 L = 1, R = 5 L = 3, R = 6 L = 9, R = 30
Output : 2 5 4 5
Explanation : For the first query, in range [1, 2] all numbers i.e. 1 and 2 can be expressed as a subset sum, 1 as 1, 2 as 2. For the second query, in range [1, 5] all numbers i.e. 1, 2, 3, 4 and 5 can be expressed as subset sum, 1 as 1, 2 as 2, 3 as 3, 4 as 2 + 2 or 1 + 3, 5 as 5. For the third query, in range [3, 6], all numbers i.e. 3, 4, 5 and 6 can be expressed as subset sum. For the last query, only numbers 9, 10, 11, 12, 13 can be expressed as subset sum, 9 as 5 + 2 + 2, 10 as 5 + 2 + 2 + 1, 11 as 5 + 3 + 2 + 1, 12 as 5 + 3 + 2 + 2 and 13 as 5 + 3 + 2 + 2 + 1.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: The idea is to use a bitset and iterate over the array to represent all possible subset sums. The current state of bitset is defined by ORing it with the previous state of bitset left shifted X times where X is the current element processed in the array. To answer the queries in O(1) time, we can precompute the count of numbers upto every number and for a range [L, R], the answer would be pre[R] – pre[L – 1], where pre[] is the precomputed array.

Below is the implementation of the above approach.

## C++

 `// CPP Program to answer subset``// sum queries in a given range``#include ``using` `namespace` `std;` `const` `int` `MAX = 1001;``bitset bit;` `// precomputation array``int` `pre[MAX];` `// structure to represent query``struct` `que {``    ``int` `L, R;``};` `void` `answerQueries(``int` `Q, que Queries[], ``int` `N,``                ``int` `arr[])``{``    ``// Setting bit at 0th position as 1``    ``bit = 1;``    ``for` `(``int` `i = 0; i < N; i++)``        ``bit |= (bit << arr[i]);` `    ``// Precompute the array``    ``for` `(``int` `i = 1; i < MAX; i++)``        ``pre[i] = pre[i - 1] + bit[i];` `    ``// Answer Queries``    ``for` `(``int` `i = 0; i < Q; i++) {``        ``int` `l = Queries[i].L;``        ``int` `r = Queries[i].R;``        ``cout << pre[r] - pre[l - 1] << endl;``    ``}``}` `// Driver Code to test above function``int` `main()``{``    ``int` `arr[] = { 1, 2, 2, 3, 5 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``    ``int` `M = 4;``    ``que Queries[M];``    ``Queries.L = 1, Queries.R = 2;``    ``Queries.L = 1, Queries.R = 5;``    ``Queries.L = 3, Queries.R = 6;``    ``Queries.L = 9, Queries.R = 30;``    ``answerQueries(M, Queries, N, arr);``    ``return` `0;``}`

## Java

 `import` `java.util.Arrays;` `// Class to represent query``class` `Que {``  ``int` `L, R;` `  ``Que(``int` `L, ``int` `R) {``    ``this``.L = L;``    ``this``.R = R;``  ``}``}` `public` `class` `Main {``  ``private` `static` `final` `int` `MAX = ``1001``;``  ``private` `static` `boolean``[] bit = ``new` `boolean``[MAX];` `  ``// Precomputation array``  ``private` `static` `int``[] pre = ``new` `int``[MAX];` `  ``public` `static` `void` `answerQueries(``int` `Q, Que[] Queries, ``int` `N, ``int``[] arr) {``    ``// Setting bit at 0th position as 1``    ``bit[``0``] = ``true``;``    ``for` `(``int` `i = ``0``; i < N; i++) {``      ``for` `(``int` `j = MAX - ``1``; j >= arr[i]; j--) {``        ``bit[j] |= bit[j - arr[i]];``      ``}``    ``}` `    ``// Precompute the array``    ``for` `(``int` `i = ``1``; i < MAX; i++) {``      ``pre[i] = pre[i - ``1``] + (bit[i] ? ``1` `: ``0``);``    ``}` `    ``// Answer Queries``    ``for` `(``int` `i = ``0``; i < Q; i++) {``      ``int` `l = Queries[i].L;``      ``int` `r = Queries[i].R;``      ``System.out.println(pre[r] - pre[l - ``1``]);``    ``}``  ``}` `  ``// Driver Code to test above function``  ``public` `static` `void` `main(String[] args) {``    ``int``[] arr = {``1``, ``2``, ``2``, ``3``, ``5``};``    ``int` `N = arr.length;``    ``int` `M = ``4``;``    ``Que[] Queries = {``new` `Que(``1``, ``2``), ``new` `Que(``1``, ``5``), ``new` `Que(``3``, ``6``), ``new` `Que(``9``, ``30``)};``    ``answerQueries(M, Queries, N, arr);``  ``}``}`

## Python3

 `from` `typing ``import` `List` `MAX` `=` `1001``bit ``=` `[``0``] ``*` `MAX` `# precomputation array``pre ``=` `[``0``] ``*` `MAX` `# structure to represent query``class` `Que:``    ``def` `__init__(``self``, L, R):``        ``self``.L ``=` `L``        ``self``.R ``=` `R` `def` `answerQueries(Q: ``int``, Queries: ``List``[Que], N: ``int``, arr: ``List``[``int``]) ``-``> ``None``:``    ``global` `bit, pre``    ``# Setting bit at 0th position as 1``    ``bit[``0``] ``=` `1``    ``for` `i ``in` `range``(N):``        ``bit ``=` `[b ``or` `(bit[j ``-` `arr[i]] ``if` `j ``-` `arr[i] >``=` `0` `else` `0``) ``for` `j, b ``in` `enumerate``(bit)]` `    ``# Precompute the array``    ``for` `i ``in` `range``(``1``, ``MAX``):``        ``pre[i] ``=` `pre[i ``-` `1``] ``+` `bit[i]` `    ``# Answer Queries``    ``for` `i ``in` `range``(Q):``        ``l ``=` `Queries[i].L``        ``r ``=` `Queries[i].R``        ``print``(pre[r] ``-` `pre[l ``-` `1``])` `# Driver Code to test above function``if` `__name__ ``=``=` `"__main__"``:``    ``arr ``=` `[``1``, ``2``, ``2``, ``3``, ``5``]``    ``N ``=` `len``(arr)``    ``M ``=` `4``    ``Queries ``=` `[Que(``1``, ``2``), Que(``1``, ``5``), Que(``3``, ``6``), Que(``9``, ``30``)]``    ``answerQueries(M, Queries, N, arr)`

## C#

 `using` `System;` `public` `class` `GFG``{``    ``private` `const` `int` `MAX = 1001;``    ``private` `static` `bool``[] bit = ``new` `bool``[MAX];` `    ``// Precomputation array``    ``private` `static` `int``[] pre = ``new` `int``[MAX];` `    ``// Class to represent query``    ``public` `class` `Que``    ``{``        ``public` `int` `L, R;` `        ``public` `Que(``int` `L, ``int` `R)``        ``{``            ``this``.L = L;``            ``this``.R = R;``        ``}``    ``}` `    ``public` `static` `void` `answerQueries(``int` `Q, Que[] Queries, ``int` `N, ``int``[] arr)``    ``{``        ``// Setting bit at 0th position as 1``        ``bit = ``true``;``        ``for` `(``int` `i = 0; i < N; i++)``        ``{``            ``for` `(``int` `j = MAX - 1; j >= arr[i]; j--)``            ``{``                ``bit[j] |= bit[j - arr[i]];``            ``}``        ``}` `        ``// Precompute the array``        ``for` `(``int` `i = 1; i < MAX; i++)``        ``{``            ``pre[i] = pre[i - 1] + (bit[i] ? 1 : 0);``        ``}` `        ``// Answer Queries``        ``for` `(``int` `i = 0; i < Q; i++)``        ``{``            ``int` `l = Queries[i].L;``            ``int` `r = Queries[i].R;``            ``Console.WriteLine(pre[r] - pre[l - 1]);``        ``}``    ``}` `    ``// Driver Code to test above function``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int``[] arr = { 1, 2, 2, 3, 5 };``        ``int` `N = arr.Length;``        ``int` `M = 4;``        ``Que[] Queries = { ``new` `Que(1, 2), ``new` `Que(1, 5), ``new` `Que(3, 6), ``new` `Que(9, 30) };``        ``answerQueries(M, Queries, N, arr);``    ``}``}`

## Javascript

 `// JavaScript Program to answer subset``// sum queries in a given range` `const MAX = 1001;``let bit = Array(MAX).fill(0);` `// precomputation array``let pre = Array(MAX).fill(0);` `// class to represent query``class Que {``constructor(L, R) {``this``.L = L;``this``.R = R;``}``}` `function` `answerQueries(Q, Queries, N, arr) {``// Setting bit at 0th position as 1``bit = 1;``for` `(let i = 0; i < N; i++) {``for` `(let j = MAX - 1; j >= arr[i]; j--) {``bit[j] |= bit[j - arr[i]];``}``}``// Precompute the array``for` `(let i = 1; i < MAX; i++) {``    ``pre[i] = pre[i - 1] + bit[i];``}` `// Answer Queries``for` `(let i = 0; i < Q; i++) {``    ``let l = Queries[i].L;``    ``let r = Queries[i].R;``    ``console.log(pre[r] - pre[l - 1]);``}``}` `// Driver Code to test above function``let arr = [1, 2, 2, 3, 5];``let N = arr.length;``let M = 4;``let Queries = [``new` `Que(1, 2), ``new` `Que(1, 5), ``new` `Que(3, 6), ``new` `Que(9, 30)];``answerQueries(M, Queries, N, arr);`

Output

```2
5
4
5```

Time Complexity: Each query can be answered in O(1) time and precomputation requires O(MAX) time.
Auxiliary Space: O(MAX)

My Personal Notes arrow_drop_up