Problem Description
Given an array of integers (each between 1 and 30), count the number of subsets (different by indices chosen) such that the product of the numbers in the subset can be represented as a product of one or more distinct prime numbers. In other words, the subset’s product must be square-free (ignoring the factor 1) and composed solely of primes that occur at most once in the factorization. Since subsets containing the number 1 do not affect the product, they have an effect in the total count by “multiplying” the number of valid combinations. The answer must be returned modulo 10^9 + 7.
Key Insights
- Only numbers that are square-free (i.e. none of their prime factors appears more than once) can contribute to a valid product; hence, numbers like 4, 8, 9, etc. are not allowed.
- Represent each valid number’s prime factors using a bitmask, where each bit corresponds to one of the prime numbers up to 30 (specifically: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29).
- Use dynamic programming (DP) where the state is defined by a bitmask representing the primes that have already been used.
- The number 1 is special: since it does not change the product, count how many times 1 appears and later multiply the result by 2^(count of 1's) (adjusting for the empty set).
- Iterate through each valid number, updating the DP states if its corresponding bitmask does not conflict with the current state.
Space and Time Complexity
Time Complexity: O(n + (2^P * M))
- n = length of the array (up to 10^5)
- P = number of primes (fixed at 10)
- M = number of valid numbers (at most 19)
Space Complexity: O(2^P) (for the DP array)
Solution
The solution uses a DP approach leveraging bitmasking:
- Precompute the frequency of each number in the array.
- Filter out numbers that are not square‐free (except 1) and convert each valid number (2 ≤ num ≤ 30) into a bitmask based on its prime factors. If a number has a squared prime factor, skip it.
- Use a DP array of size 2^(number of primes) (1024) where dp[state] represents the number of ways to achieve that prime combination.
- For each valid number (with its frequency and bitmask), iterate over the DP states in reverse to avoid overcounting. For every state that can accommodate the new number (no overlapping prime factors), update the DP for the combined state by adding dp[old_state] * (frequency of the number).
- Sum up all DP states except the empty state to get the number of valid subsets.
- Multiply the result by 2^(frequency of 1) to account for the inclusion of ones in every subset.
- Return the answer modulo 10^9 + 7.