Approach
Lets say you have a number n
that goes up to 1018 and you want to prime factorise it. Since this number can be as small as unity and as big as 1018, all along it can be prime as well as composite, this would be my approach -
- Using 米勒·拉宾素性测试,确保该数字是合数。
- Factorise
n
using primes up to 106, which can be calculated using sieve of Eratosthenes.
Now the updated value of n
is such that it has prime factors only above 106 and since the value of n
can still be as big as 1018, we conclude that the number is either prime or it has exactly two prime factors (not necessarily distinct).
- 再次运行 Miller Rabin 以确保该数字不是质数。
- Use Pollard rho 算法得到一个素因数。
现在你已经完成了因式分解。
让我们看看上述方法的时间复杂度:
- 米勒·拉宾接受
O(log n)
- 埃拉托斯特尼筛法
O(n*log n)
- 我分享的 Pollard rho 的实现需要
O(n^0.25)
时间复杂度
步骤 2 花费的最大时间等于O(10^7)
,这又是上述算法的复杂度。这意味着您可以在一秒钟内找到几乎所有编程语言的因式分解。
空间复杂度
空间仅在实施筛子的步骤 2 中使用,并且等于O(10^6)
。再次强调,非常实用。
执行
完整代码实施于C++14
。该代码有一个隐藏的错误。您可以在下一部分中揭示它,也可以跳到挑战;)
代码中的错误
In line 105
,迭代直到i<=np
。否则,您可能会错过以下情况prime[np]=999983
是一个素因数
挑战
给我一个值n
,如果有的话,其中共享代码导致错误的素因数分解。
Bonus
有多少个这样的值n
exist ?
Hint
对于这样的 n 值,断言Line 119
可能会失败。
Solution
我们打电话吧P=999983
。表格中的所有数字n = p*q*r
其中 p、q、r 是素数 >=P
使得其中至少一个等于P
将导致错误的质因数分解。
Bonus Solution
There are exactly four such numbers: {P03, P02P1, P02P2, P0P12}, where P0 = P = 999983, P1 = next_prime(P0) = 1000003, P2 = next_prime(P1) = 1000033.