标签:
给一个数n,快速提取n的一个因数。
讲生日悖论之前,先看一个东西。
给出[1..1000]的数,从中任意选出一个数为k的概率是
但是假如选出两个数p,q要求他们的差值为k,就是|p-q|=k的概率大概是
继续向下,选出l个数,使他们之间有两个数的差值为k,那么概率会随l的变大而变大,最终会趋近于1。
接下来是生日悖论:
我们随机选择一名学生,他的生日为 4 月 1 日的概率为 [1..365]
这相当于我们在[1..365]中随机选取一个数,该数为 90 的概率是多少?
那么我们又回到了上面那个问题。
我们随机选取 k(k≥ 2)个人 ,他们的生日相同的概率是多少(就是差值为0)?
我们可以看到,k = 10 的时候大概有 11%的可能性存在两个人生日相同的情况,
而 k = 23 时,可能性提高至50%,假如一个班级总共有57个人,而l=57时的可能性已达到99%,几乎可以肯定地说,一个班级里必定有两个同学的出生日期是相同的,而这么多年的求学生涯过来了,这个概率“似乎”是不正确的,这便是悖论了。
那么竟然有了这个玄学的悖论,我们就可以随机的快速分解n了,2333。
有一个随机函数f(x)=(x*x+d)%n,d=rand()。然后每次随机出来的数和上一次随机出来的数的差值与n去一个最大公因数,然后判断一下就好了。
但是假如一直找不到符合的数然后死循环了怎么办。
我们可以用Floyd发明的机智判环算法,因为我每次a=f(a),再找一个b=f(f(b)),如果有一个时刻a=b那么就退出循环,因为b是以两倍的速度走得,当b追上了a,那么b至少已经走完一圈了。
复杂度O(
随机函数f
ll f(ll x){
int u=rand();
return (cheng(x,x,n)+po)%n;
}
Pollard’s Rho 算法
a=0;
b=1;
po=rand()%n+1;
while(1){
a=b=rand()%n+1;
while(1){
a=f(a);
b=f(f(b));
if(a==b)break;
ll ui=abs(b-a);
ll tt=gcd(ui,n);
if(tt==1||tt==n)continue;
if(tt>1){
p=tt;
break;
}
}
po--;
if(p)break;
}
标签:
原文地址:http://blog.csdn.net/doyouseeman/article/details/51204612