# Time: O(n + m * 2^p) # Space: O(m * 2^p) import collections # number theory, combinatorics, bitmasks, dp class Solution(object): def squareFreeSubsets(self, nums): """ :type nums: List[int] :rtype: int """ def linear_sieve_of_eratosthenes(n): # Time: O(n), Space: O(n) primes = [] spf = [-1]*(n+1) # the smallest prime factor for i in xrange(2, n+1): if spf[i] == -1: spf[i] = i primes.append(i) for p in primes: if i*p > n or p > spf[i]: break spf[i*p] = p return primes MAX_NUM = max(nums) PRIMES = linear_sieve_of_eratosthenes(MAX_NUM) MASKS = [0]*(MAX_NUM+1) for x in xrange(MAX_NUM+1): y = x for i, p in enumerate(PRIMES): if y%p: continue if y%p**2 == 0: MASKS[x] = 0 break MASKS[x] |= (1< n or p > spf[i]: break spf[i*p] = p return primes MAX_NUM = max(nums) PRIMES = linear_sieve_of_eratosthenes(MAX_NUM) MASKS = [0]*(MAX_NUM+1) for x in xrange(MAX_NUM+1): y = x for i, p in enumerate(PRIMES): if y%p: continue if y%p**2 == 0: MASKS[x] = 0 break MASKS[x] |= (1<