# Counting Subsets with prime product property

Last Updated : 17 Aug, 2023

Given an array arr[] of size N. The task is to find a number of subsets whose product can be represented as a product of one or more distinct prime numbers. Modify your answer to the modulo of 109 + 7.

Example:

Input: N = 4, arr[] = {1, 2, 3, 4}
Output: 6
Explanation: The good subsets are:

• [1, 2]: product is 2, which is the product of distinct prime 2.
• [1, 2, 3]: product is 6, which is the product of distinct primes 2 and 3.
• [1, 3]: product is 3, which is the product of distinct prime 3.
• [2]: product is 2, which is the product of distinct prime 2.
• [2, 3]: product is 6, which is the product of distinct primes 2 and 3.
• [3]: product is 3, which is the product of distinct prime 3.

Input: N = 3, arr[] =  {2, 2, 3}
Output: 5
Explanation: The good subsets are : {2}, {2}, {2, 3}, {2, 3}, {3}

Approach: This can be solved with the following idea:

The general approach for the given problem is to use dynamic programming to count the number of good subsets.

Below are the steps involved in the implementation of the code:

• Create a static array map with a size of 31, along with a constant mod of 109 + 7.
• Find the prime factors of each integer i from 2 to 30 and set the associated bits in map[i] if i is not a multiple of 4 or 9 or equal to 25.
• Set the first member of the integer array dp to 1 and initialize the integer variables one and cnt to have sizes of 1024 and 31, respectively  Step 4: If the appropriate map[i] value is non-zero and the integer i is not 1, increment one for each integer i in the provided array arr; otherwise, increment the count of i in the cnt array.
• For each index, i in the cnt array where the value is non-zero, iterate through all the possible subsets of prime numbers using a nested loop over all the possible j values from 0 to 1023. If the jth bit is set and the map[i]th bit is also set, skip to the next j. Otherwise, update the dp[j| map[i]] value with the sum of its current value and the product of the count of i and the dp[j] value.
• After the loops are complete, initialize a long variable res as 0, iterate through all the elements of the dp array, and update the res value as the sum of its current value and the current element’s value. Then decrement res by 1.
• If the one value is non-zero, calculate its power using a helper function pow and multiply the result with res. Finally, return the result as an i integer.

Below is the code implementation of the above method:

## C++

 `// C++ code of the above approach` `#include ` `using` `namespace` `std;` `#define mod 1000000007`   `int` `map_[31];`   `// Function to calculate power` `long` `long` `pow``(``int` `n)` `{` `    ``long` `long` `res = 1, m = 2;` `    ``while` `(n != 0) {` `        ``if` `((n & 1) == 1)` `            ``res = (res * m) % mod;` `        ``m = m * m % mod;` `        ``n >>= 1;` `    ``}` `    ``return` `res;` `}`   `// Check for prime value` `void` `check_prime_val()` `{` `    ``int` `prime[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };` `    ``for` `(``int` `i = 2; i <= 30; ++i) {` `        ``// If num is a multiple of` `        ``// 4/9/25, adding it to any` `        ``// subset will make it bad` `        ``if` `(i % 4 == 0 || i % 9 == 0 || i == 25)` `            ``continue``;` `        ``int` `mask = 0;` `        ``for` `(``int` `j = 0; j < 10; ++j) {` `            ``if` `(i % prime[j] == 0)` `                ``mask |= 1 << j;` `        ``}` `        ``map_[i] = mask;` `    ``}` `}`   `int` `goodSubsets(``int` `arr[], ``int` `n)` `{` `    ``int` `one = 0;` `    ``// dp[set_of_primes] represents` `    ``// the number of times set_of_primes` `    ``// can be formed (set_of_primes ===` `    ``// mask) Since there are 10 possible` `    ``// prime numbers, there are 2^10` `    ``// possible set_of_primes` `    ``int` `dp[1024] = { 0 }, cnt[31] = { 0 };` `    ``dp[0] = 1;` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``if` `(arr[i] == 1)` `            ``one++;` `        ``else` `if` `(map_[arr[i]] != 0)` `            ``cnt[arr[i]]++;` `    ``}` `    ``for` `(``int` `i = 0; i < 31; ++i) {` `        ``if` `(cnt[i] == 0)` `            ``continue``;` `        ``for` `(``int` `j = 0; j < 1024; ++j) {` `            ``if` `((j & map_[i]) != 0)` `                ``continue``;` `            ``dp[j | map_[i]]` `                ``= (dp[j | map_[i]] + dp[j] * cnt[i]) % mod;` `        ``}` `    ``}` `    ``long` `res = 0;` `    ``for` `(``int` `i : dp)` `        ``res = (res + i) % mod;` `    ``res--;` `    ``if` `(one != 0)` `        ``res = res * ``pow``(one) % mod;` `    ``return` `res;` `}` `// Driver code` `int` `main()` `{` `    ``int` `arr[] = { 1, 2, 3, 4 };` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]);`   `    ``check_prime_val();` `    ``// Function call` `    ``cout << goodSubsets(arr, n) << endl;`   `    ``return` `0;` `}` `// This code is contributed by Tapesh(tapeshdua420)`

## Java

 `// Java code of the above approach` `class` `Solution {`   `    ``static` `int` `mod = (``int``)1e9 + ``7``;`   `    ``static` `int``[] map = ``new` `int``[``31``];`   `    ``// Check for prime value` `    ``static` `    ``{` `        ``int``[] prime = ``new` `int``[] { ``2``, ``3``, ``5``, ``7``, ``11``,` `                                  ``13``, ``17``, ``19``, ``23``, ``29` `};` `        ``for` `(``int` `i = ``2``; i <= ``30``; ++i) {`   `            ``// If num is a multiple of` `            ``// 4/9/25, adding it to any` `            ``// subset will make it bad` `            ``if` `(``0` `== i % ``4` `|| ``0` `== i % ``9` `|| ``25` `== i)` `                ``continue``;` `            ``int` `mask = ``0``;` `            ``for` `(``int` `j = ``0``; j < ``10``; ++j) {` `                ``if` `(``0` `== i % prime[j])` `                    ``mask |= ``1` `<< j;` `            ``}` `            ``map[i] = mask;` `        ``}` `    ``}`   `    ``public` `int` `goodSubsets(``int``[] arr, ``int` `n)` `    ``{`   `        ``int` `one = ``0``;`   `        ``// dp[set_of_primes] represents` `        ``// the number of times set_of_primes` `        ``// can be formed (set_of_primes ===` `        ``// mask) Since there are 10 possible` `        ``// prime numbers, there are 2^10` `        ``// possible set_of_primes` `        ``int``[] dp = ``new` `int``[``1024``], cnt = ``new` `int``[``31``];` `        ``dp[``0``] = ``1``;` `        ``for` `(``int` `i : arr) {` `            ``if` `(i == ``1``)` `                ``one++;` `            ``else` `if` `(map[i] != ``0``)` `                ``cnt[i]++;` `        ``}` `        ``for` `(``int` `i = ``0``; i < ``31``; ++i) {` `            ``if` `(cnt[i] == ``0``)` `                ``continue``;` `            ``for` `(``int` `j = ``0``; j < ``1024``; ++j) {` `                ``if` `(``0` `!= (j & map[i]))` `                    ``continue``;` `                ``dp[j | map[i]]` `                    ``= (``int``)((dp[j | map[i]]` `                             ``+ dp[j] * (``long``)cnt[i])` `                            ``% mod);` `            ``}` `        ``}` `        ``long` `res = ``0``;` `        ``for` `(``int` `i : dp)` `            ``res = (res + i) % mod;` `        ``res--;` `        ``if` `(one != ``0``)` `            ``res = res * pow(one) % mod;` `        ``return` `(``int``)res;` `    ``}`   `    ``// Function to calculate power` `    ``public` `long` `pow(``int` `n)` `    ``{` `        ``long` `res = ``1``, m = ``2``;` `        ``while` `(n != ``0``) {` `            ``if` `(``1` `== (n & ``1``))` `                ``res = (res * m) % mod;` `            ``m = m * m % mod;` `            ``n >>= ``1``;` `        ``}` `        ``return` `res;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int``[] arr = { ``1``, ``2``, ``3``, ``4` `};` `        ``int` `n = arr.length;` `        ``Solution solution = ``new` `Solution();`   `        ``// Function call` `        ``int` `result = solution.goodSubsets(arr, n);`   `        ``System.out.println(result);` `    ``}` `}`

## Python3

 `# Python3 code of the above approach` `from` `typing ``import` `List`     `class` `Solution:` `    ``mod ``=` `int``(``1e9` `+` `7``)` `    ``map` `=` `[``0``] ``*` `31`   `    ``# Check for prime value` `    ``@staticmethod` `    ``def` `calculatePrimes():` `        ``prime ``=` `[``2``, ``3``, ``5``, ``7``, ``11``, ``13``, ``17``, ``19``, ``23``, ``29``]` `        ``for` `i ``in` `range``(``2``, ``31``):` `            ``if` `i ``%` `4` `=``=` `0` `or` `i ``%` `9` `=``=` `0` `or` `i ``=``=` `25``:` `                ``continue` `            ``mask ``=` `0` `            ``for` `j ``in` `range``(``10``):` `                ``if` `i ``%` `prime[j] ``=``=` `0``:` `                    ``mask |``=` `(``1` `<< j)` `            ``Solution.``map``[i] ``=` `mask`   `    ``def` `goodSubsets(``self``, arr: ``List``[``int``], n: ``int``) ``-``> ``int``:` `        ``one ``=` `0` `        ``dp ``=` `[``0``] ``*` `1024` `        ``cnt ``=` `[``0``] ``*` `31` `        ``dp[``0``] ``=` `1`   `        ``for` `i ``in` `arr:` `            ``if` `i ``=``=` `1``:` `                ``one ``+``=` `1` `            ``elif` `Solution.``map``[i] !``=` `0``:` `                ``cnt[i] ``+``=` `1`   `        ``for` `i ``in` `range``(``31``):` `            ``if` `cnt[i] ``=``=` `0``:` `                ``continue` `            ``for` `j ``in` `range``(``1024``):` `                ``if` `j & Solution.``map``[i]:` `                    ``continue` `                ``dp[j | Solution.``map``[i]] ``=` `(` `                    ``dp[j | Solution.``map``[i]] ``+` `dp[j] ``*` `cnt[i]) ``%` `Solution.mod`   `        ``res ``=` `0` `        ``for` `i ``in` `dp:` `            ``res ``=` `(res ``+` `i) ``%` `Solution.mod` `        ``res ``-``=` `1`   `        ``if` `one !``=` `0``:` `            ``pow_val ``=` `1` `            ``m ``=` `2` `            ``while` `one !``=` `0``:` `                ``if` `one & ``1``:` `                    ``pow_val ``=` `(pow_val ``*` `m) ``%` `Solution.mod` `                ``m ``=` `(m ``*` `m) ``%` `Solution.mod` `                ``one >>``=` `1` `            ``res ``=` `(res ``*` `pow_val) ``%` `Solution.mod`   `        ``return` `int``(res)`   `    ``# Driver code` `    ``def` `main(``self``):` `        ``arr ``=` `[``1``, ``2``, ``3``, ``4``]` `        ``n ``=` `len``(arr)`   `        ``# Calculate primes` `        ``Solution.calculatePrimes()`   `        ``# Create an instance of the class` `        ``solution ``=` `Solution()`   `        ``# Function call` `        ``result ``=` `solution.goodSubsets(arr, n)`   `        ``print``(result)`     `# Create an instance of the Solution class` `solution ``=` `Solution()`   `# Call the main function` `solution.main()`   `# This code is contributed by shivamgupta0987654321`

## C#

 `// c# code for above approach` `using` `System;`   `class` `Program {` `    ``const` `int` `mod = 1000000007;`   `    ``static` `int``[] map_ = ``new` `int``[31];`   `    ``// Function to calculate power` `    ``static` `long` `Pow(``int` `n)` `    ``{` `        ``long` `res = 1;` `        ``long` `m = 2;` `        ``while` `(n != 0) {` `            ``if` `((n & 1) == 1)` `                ``res = (res * m) % mod;` `            ``m = (m * m) % mod;` `            ``n >>= 1;` `        ``}` `        ``return` `res;` `    ``}`   `    ``// Check for prime value` `    ``static` `void` `CheckPrimeVal()` `    ``{` `        ``int``[] prime` `            ``= { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };` `        ``for` `(``int` `i = 2; i <= 30; ++i) {` `            ``// If num is a multiple of` `            ``// 4/9/25, adding it to any` `            ``// subset will make it bad` `            ``if` `(i % 4 == 0 || i % 9 == 0 || i == 25)` `                ``continue``;` `            ``int` `mask = 0;` `            ``for` `(``int` `j = 0; j < 10; ++j) {` `                ``if` `(i % prime[j] == 0)` `                    ``mask |= 1 << j;` `            ``}` `            ``map_[i] = mask;` `        ``}` `    ``}`   `    ``static` `int` `GoodSubsets(``int``[] arr, ``int` `n)` `    ``{` `        ``int` `one = 0;` `        ``// dp[set_of_primes] represents` `        ``// the number of times set_of_primes` `        ``// can be formed (set_of_primes ===` `        ``// mask) Since there are 10 possible` `        ``// prime numbers, there are 2^10` `        ``// possible set_of_primes` `        ``int``[] dp = ``new` `int``[1024];` `        ``int``[] cnt = ``new` `int``[31];` `        ``dp[0] = 1;` `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``if` `(arr[i] == 1)` `                ``one++;` `            ``else` `if` `(map_[arr[i]] != 0)` `                ``cnt[arr[i]]++;` `        ``}` `        ``for` `(``int` `i = 0; i < 31; ++i) {` `            ``if` `(cnt[i] == 0)` `                ``continue``;` `            ``for` `(``int` `j = 0; j < 1024; ++j) {` `                ``if` `((j & map_[i]) != 0)` `                    ``continue``;` `                ``dp[j | map_[i]]` `                    ``= (dp[j | map_[i]] + dp[j] * cnt[i])` `                      ``% mod;` `            ``}` `        ``}` `        ``long` `res = 0;` `        ``foreach``(``int` `i ``in` `dp) res = (res + i) % mod;` `        ``res--;` `        ``if` `(one != 0)` `            ``res = (res * Pow(one)) % mod;` `        ``return` `(``int``)res;` `    ``}`   `    ``// Driver code` `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``int``[] arr = { 1, 2, 3, 4 };` `        ``int` `n = arr.Length;`   `        ``CheckPrimeVal();` `        ``// Function call` `        ``Console.WriteLine(GoodSubsets(arr, n));` `    ``}` `}`

## Javascript

 `const mod = 1000000007;` `const map_ = ``new` `Array(31).fill(0);`   `// Function to calculate power` `function` `pow(n) {` `  ``let res = 1;` `  ``let m = 2;` `  ``while` `(n !== 0) {` `    ``if` `((n & 1) === 1) {` `      ``res = (res * m) % mod;` `    ``}` `    ``m = (m * m) % mod;` `    ``n >>= 1;` `  ``}` `  ``return` `res;` `}`   `// Check for prime value` `function` `check_prime_val() {` `  ``const prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];` `  ``for` `(let i = 2; i <= 30; ++i) {` `  `  `      ``// If num is a multiple of` `    ``// 4/9/25, adding it to any` `   ``// subset will make it bad` `    ``if` `(i % 4 === 0 || i % 9 === 0 || i === 25) {` `      ``continue``;` `    ``}` `    ``let mask = 0;` `    ``for` `(let j = 0; j < 10; ++j) {` `      ``if` `(i % prime[j] === 0) {` `        ``mask |= 1 << j;` `      ``}` `    ``}` `    ``map_[i] = mask;` `  ``}` `}`   `function` `goodSubsets(arr, n) {` `  ``let one = 0;` `  `  `  ``// dp[set_of_primes] represents` `  ``// the number of times set_of_primes` `  ``// can be formed (set_of_primes ===` `  ``// mask) Since there are 10 possible` `  ``// prime numbers, there are 2^10` `  ``// possible set_of_primes` `  ``const dp = ``new` `Array(1024).fill(0);` `  ``const cnt = ``new` `Array(31).fill(0);` `  ``dp[0] = 1;` `  ``for` `(let i = 0; i < n; i++) {` `    ``if` `(arr[i] === 1) {` `      ``one++;` `    ``} ``else` `if` `(map_[arr[i]] !== 0) {` `      ``cnt[arr[i]]++;` `    ``}` `  ``}` `  ``for` `(let i = 0; i < 31; ++i) {` `    ``if` `(cnt[i] === 0) {` `      ``continue``;` `    ``}` `    ``for` `(let j = 0; j < 1024; ++j) {` `      ``if` `((j & map_[i]) !== 0) {` `        ``continue``;` `      ``}` `      ``dp[j | map_[i]] = (dp[j | map_[i]] + dp[j] * cnt[i]) % mod;` `    ``}` `  ``}` `  ``let res = 0;` `  ``for` `(let i of dp) {` `    ``res = (res + i) % mod;` `  ``}` `  ``res--;` `  ``if` `(one !== 0) {` `    ``res = (res * pow(one)) % mod;` `  ``}` `  ``return` `res;` `}`   `// Driver code` `const arr = [1, 2, 3, 4];` `const n = arr.length;` `check_prime_val();`   `console.log(goodSubsets(arr, n));`

Output

```6

```

Time Complexity: O(N*logN)
Auxiliary Space: O(N)

Article Tags :
Practice Tags :