质数
什么是质数?
一个正整数无法被除了1和自己之外的任何自然数整除
特殊情况 1既不是质数也不是合数
质数的数量 不超过N的质数大约有N/lnN个
质数的判定
一般使用试除法判断质数
若一个正整数N为合数,则存在一个能整除N的数 T 且T∈[2,√N]
证明方法:反证法
1 | bool isprime(int n){ |
质数的筛选
Eratosthenes
任意的整数N的倍数2N,3N……必定为合数
复杂度O(N log log N)趋于线性,比较常用
1 | void prime(int n){ |
线性筛
在生成一个合数时,每次只向现有的数乘上一个质因子,并且让它是这个合数的最小质因子,这样可以避免重复标记合数
复杂度O(N)
1 | int v[MAX_N],prime[MAX_N]; |
算术基本定理
任何一个大于 1 的正整数都能有限分解为有限个质数的乘积
N=p1^c1*p2^c2*...*pn^cn
其中ci都是正整数 pi都是质数 且满足p1<p2<p3<…<pn
质因数分解
根据算术基本定理,我们可以分解正整数N
试除法
扫描2-√N的每个数d,若d能整除N,则从N中除掉所有的d,同时累积除去d的个数
1 | void divide(int n){ |
pollard‘s Rho
对于一个大整数n,我们取任意一个数xx使得xx是nn的质因数的几率很小,但如果取两个数x1x1以及x2x2使得它们的差是n的因数的几率就提高了,如果取x1x1以及x2x2使得gcd(abs(x1−x2),n)>1gcd(abs(x1−x2),n)>1的概率就更高了。
其实,这是生日悖论
生日问题是指,如果一个房间里有23个或23个以上的人,那么至少有两个人的生日相同的概率要大于50%。这就意味着在一个典型的标准小学班级(30人)中,存在两人生日相同的可能性更高。对于60或者更多的人,这种概率要大于99%。从引起逻辑矛盾的角度来说生日悖论并不是一种悖论,从这个数学事实与一般直觉相抵触的意义上,它才称得上是一个悖论。大多数人会认为,23人中有2人生日相同的概率应该远远小于50%。
对于满足gcd(abs(x1−x2),n)>1gcd(abs(x1−x2),n)>1的x1x1和x2x2,gcd(abs(x1−x2),n)gcd(abs(x1−x2),n)就是n的一个因数,只需要判断它是否为素数,若为素数,则是n的质因数,否则递归此过程。
那么我们怎样不断取得x1x1和x2x2呢? x1x1在区间[1,n][1,n]中随机出来,而x2x2则由x[i]=(x[i-1]*x[i-1]%n+c)%n
推算出来,其中cc为任意给定值,事实证明,这样就是比较优的。
1 | #include<cstdio> |