您的問題有一個簡單而有效的解決方案。需要注意的是n!
是:
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * ... * n
讓我們想想一個主要因素有多少次出現在本產品,例如2
。 每隔2
出現一次。但每4
因素一次出現兩次。並且每8
因子一次出現三次等。 換句話說,因子2
將出現在n!
sum(n//(2**e) for e in range(1, n))
次。對於任何主要因素k
也是如此。
您可以實現此計算有:現在
import itertools as it
def exp_for_factor_in_factorial(factor, n):
total = 0
for e in it.count(1):
if factor ** e > n:
break
total += n // factor**e
return total
,爲了找到我們需要找到所有素數達n
的n!
所有的主要因素,這是很容易使用埃拉托色尼完成:
import math
def sieve(n):
nums = [True] * (n+1)
nums[:2] = [False]*2
nums[4::2] = [False] * math.ceil((n-3)/2)
for i in range(3, int((n+1)**.5)+1, 2):
if nums[i]:
for j in range(i*i, n+1, 2*i):
nums[j] = False
return [i for i,k in enumerate(nums) if k]
這使我們能夠獲得的n!
的分解:
def get_factorization_factorial(n):
primes = sieve(n)
factors = []
for p in primes:
factors.append((p, exp_for_factor_in_factorial(p, n)))
return factors
最後,計算除數的數量從因式分解你可以使用你已經提到的公式:
import operator as op
from functools import reduce
def get_num_divisors(factorization):
return reduce(op.mul, (e+1 for _, e in factorization), 1)
所以最終的答案可以作爲獲得:
def divs_of_squared_fact(n):
return get_num_divisors((p, 2*e) for p, e in get_factorization_factorial(n))
請注意,此解決方案極其比你更好的性能:
In [41]: %%timeit
...: for i in range(2, 1000):
...: x = divs_of_squared_fact(i)
...:
1 loops, best of 3: 276 ms per loop
In [42]: %%timeit
...: for i in range(2, 1000):
...: x = divisorsOfFactorialSquare(i)
...:
1 loops, best of 3: 7.89 s per loop
它能夠產生除數的數0在約2ms
,而另外一個需要近半秒:
In [47]: %timeit divs_of_squared_fact(5000)
100 loops, best of 3: 2.07 ms per loop
In [48]: %timeit divisorsOfFactorialSquare(5000)
1 loops, best of 3: 439 ms per loop
好吧,其實答案有不同的漸近複雜性,以便增加參數當差趨於無窮。
對於這樣的問題Vektor88我想了想,也對代碼審查你可能會發現在http://cs.stackexchange.com/ – Vektor88 2014-11-02 08:52:34
@更好的答案,但我認爲這是一個更好的地方。 – 2014-11-02 08:54:01
我不是downvoter,但我真的認爲,當它的性能,或複雜的事情,CS是一個更好的地方。但這只是一個建議。你肯定知道並使用這個網站更然後我:) – Vektor88 2014-11-02 09:16:41