Pollard-Rho 总结
将一个大数\(N\)分解质因子。
试除法,暴力枚举\(1~\sqrt{N}\)的数。时间复杂度:\(O(\sqrt{N})\)。
通常,这个复杂度够了,但有时,\(N\leq10^{18}\)。
这就需要Pollard-Rho了。
首先,考虑一种简单情况。设\(N=p*q(p<q)\)。
有一种糟糕的做法:随机法。随机一个\(1~\sqrt{N}\)的数x,判断能否整除。期望需要\(\sqrt{N}\)次。
我们发现,随机的数x并不一定要等于p,只要是p的倍数即可,即\(gcd(N,x)=p\)。
然而,这样每次的概率仍只有\(\frac{1}{\sqrt{N}}\)。
我们来考虑这样一种情况:在[1,1000]里面取一个数,取到我们想要的数(比如说,42),成功的概率是多少呢?显然是1/1000。
一个不行就取两个吧:随便在[1,1000]里面取两个数我们想办法提高准确率,就取两个数的差值绝对值。
也就是说,在[1,1000]里面任意选取两个数\(i,j\),问\(∣i−j∣=42\)的概率是多大?答案会扩大到1/500。
我们可以取\(\sqrt{p}\),即\(N^{0.25}\)个数,两两做差并与N求gcd。
但我们需要两两做差,复杂度会回去。
若\(gcd(|a-b|,N)=p\),则\(a=b (mod p)\)。(a不等于b)
然后,我们可以随机生成一个序列,看看里面是否有模p意义下相等的两个数。
但是,我们不知道p,我们只能通过求\(gcd(|a-b|,N)\)的方法来判断\(a=b (mod p)\)是否成立。就是说,我们只能判断\(a=b (mod p)\)是否成立,不能知道\(a\%p\)的值。
这个序列,我们显然可以\(rand\),但有一种更好的方法:
设序列\(A_i=f(A_{i-1})\),其中\(f(x)=x^2+y\)(y为定值)。那么,若\(a=b (mod p),f(a) mod p\)一定等于\(f(b) mod p\)。但rand就没有这个性质。
换句话说,就是mod p后的数列出现了循环(原数列没有循环)。
这样,只要找到mod p后的数列的循环即可。(若用rand(),就需要等到原数列循环,复杂度就会退化为\(\sqrt{N}\))
找循环可以用Floyd判圈,而这个算法正好是对两个进行比较的。
但是,可能原数列循环后,都没有找到解。
所以,在判圈的时候,如果原数列循环,则退出,换一个新的y计算。
根据“生日悖论”,只要选\(\sqrt{p}\)个小于p的数,就有相等的。
由于模数是\(10^{18}\)级别的,要用快速乘。
时间复杂度:\(O(N^{0.25}*logN)\)。
代码:
int sed[4]={13131,4649,65537,28627},se;
ll n;
ll gcd(ll a,ll b)
{
while(b!=0)
{
ll t=a%b;
a=b;
b=t;
}
return a;
}
ll f(ll x)
{
return (ksc(x,x,n)+se)%n;
}
ll ksc(ll a,ll b,ll md)
{
ll jg=0;
while(b>0)
{
if(b&1)
jg=(jg+a)%md;
a=(a+a)%md;
b=(b>>1);
}
return jg;
}
ll rho()
{
while(1)
{
se=sed[rand()%4];
ll z1=1,z2=f(z1);
while(z1!=z2)
{
ll t=z1-z2;
if(t<0)
t=-t;
ll g=gcd(t,n);
if(g!=1&&g!=n)
return g;
z1=f(z1);
z2=f(f(z2));
}
}
}
最新文章
- centos6u3 安装 celery 总结
- 判断线段相交 -- 51nod 1264 线段相交
- 结构体mem_pool_t
- App.config提示错误“配置系统未能初始化”
- POJ1015 动态规划
- POJ1088(dp)
- Gym101473A Gym101473E Gym101473F-前缀和
- Dynamic CRM工作流流程实战
- 给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)
- php通过imap获取腾讯企业邮箱信息后的解码处理
- Real-time chart using ASP.NET Core and WebSocket
- 高级组件——表格模型TableModel
- PAT Basic 1002
- asp.net core 2.0 后台定时自动执行任务
- luogu1984 烧水问题 (找规律)
- Lucene 个人领悟 (二)
- JavaScript -- Style
- PHP+FastCGI+Nginx配置PHP运行环境方法
- CentOS部署Kubernetes1.13集群-1(使用kubeadm安装K8S)
- iOS 9应用开发教程之定制应用程序图标以及真机测试