大数因数分解Pollard_rho 算法详解

适用范围:给你一个大数n,将它分解它的质因子的乘积的形式。

P.S. 在下面的论述中会使用到Miller_rabin和快速乘法和快速幂,如果有兴趣请看另一篇博文。

不过其实你只需要知道Miller_rabin是判断一个数是否是素数。q_mul是求(a*b)% mod,q_pow是求(a^b) % mod即可。

Miller_rabin素数判断:http://blog.csdn.net/maxichu/article/details/45458569

大数分解最简单的思想也是试除法,这里就不再展示代码了,就是从2到sqrt(n),一个一个的试验,直到除到1或者循环完,最后判断一下是否已经除到1了即可。

但是这样的做的复杂度是相当高的。一种很妙的思路是找到一个因子(不一定是质因子),然后再一路分解下去。这就是基于Miller_rabin的大数分解法Pollard_rho大数分解。

Pollard_rho算法的大致流程是 先判断当前数是否是素数(Miller_rabin)了,如果是则直接返回。如果不是素数的话,试图找到当前数的一个因子(可以不是质因子)。然后递归对该因子和约去这个因子的另一个因子进行分解。

那么自然的疑问就是,怎么找到当前数n的一个因子?当然不是一个一个慢慢试验,而是一种神奇的想法。其实这个找因子的过程我理解的不是非常透彻,感觉还是有一点儿试的意味,但不是盲目的枚举,而是一种随机化算法。我们假设要找的因子为p,他是随机取一个x1,由x1构造x2,使得{p可以整除x1-x2 && x1-x2不能整除n}则p=gcd(x1-x2,n),结果可能是1也可能不是1。如果不是1就找寻成功了一个因子,返回因子;如果是1就寻找失败,那么我们就要不断调整x2,具体的办法通常是x2=x2*x2+c(c是自己定的)直到出现x2出现了循环==x1了表示x1选取失败重新选取x1重复上述过程。(似乎还存在一个每次找寻范围*2的优化,但是不太懂。。。)

因为x1和x2再调整时最终一定会出现循环,形成一个类似希腊字母rho的形状,故因此得名。

另外通过find函数来分解素数,如果找到了一个素数因子则加入到因子map中,否则如果用Pollard找到一个因子则递归去找素数因子。

上代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;const int times = 50;
int number = 0;map<long long, int>m;
long long Random( long long n )
{return ((double)rand( ) / RAND_MAX*n + 0.5);
}long long q_mul( long long a, long long b, long long mod ) //快速乘法取模
{long long ans = 0;while(b){if(b & 1){ans += a;}b /= 2;a = (a + a) % mod;}return ans;
}long long q_pow( long long a, long long b, long long mod ) //快速乘法下的快速幂,叼
{long long ans = 1;while(b){if(b & 1){ans = q_mul( ans, a, mod );}b /= 2;a = q_mul( a, a, mod );}return ans;
}bool witness( long long a, long long n )//miller_rabin算法的精华
{long long tem = n - 1;int j = 0;while(tem % 2 == 0){tem /= 2;j++;}long long x = q_pow( a, tem, n ); //得到a^(n-1) mod nif(x == 1 || x == n - 1) return true;while(j--){x = q_mul( x, x, n );if(x = n - 1) return true;}return false;
}bool miller_rabin( long long n )  //检验n是否是素数
{if(n == 2)return true;if(n < 2 || n % 2 == 0)return false;for(int i = 1; i <= times; i++)  //做times次随机检验{long long a = Random( n - 2 ) + 1; //得到随机检验算子 aif(!witness( a, n ))  //用a检验n是否是素数return false;}return true;
}long long gcd( long long a, long long b )
{if(b == 0)return a;return gcd( b, a%b );
}long long pollard_rho( long long n, long long c )//找到n的一个因子
{long long x, y, d, i = 1, k = 2;x = Random( n - 1 ) + 1;y = x;while(1){i++;x = (q_mul( x, x, n ) + c) % n;d = gcd( y - x, n );if(1<d&&d<n)return d;if(y == x)//找到循环,选取失败,重新来return n;if(i == k) //似乎是一个优化,但是不是很清楚{y = x;k <<= 1;}}
}void find( long long n, long long c )
{if(n == 1)return;if(miller_rabin( n )){m[n]++;number++;return;}long long p = n;while(p >= n)p = pollard_rho( p, c-- );find( p, c );find( n / p, c );
}int main( )
{long long tar;while(cin >> tar){number = 0;m.clear();find( tar, 2137342 );printf( "%lld = ", tar );if(m.empty()){printf( "%lld\n", tar );}for(map<long long, int>::iterator c = m.begin(); c != m.end();){printf( "%lld^%d", c->first, c->second );if((++c) != m.end())printf( " * " );}printf( "\n" );}return 0;
}

五一最后一天好烦躁啊,,端午端午你快点儿来!

大数因数分解Pollard_rho 算法详解相关推荐

  1. 排序算法,最全的10大排序算法详解(Sort Algorithm)

    文章目录 排序算法,最全的10大排序算法详解(Sort Algorithm) 排序算法分类 排序算法稳定性 时间复杂度(time complexity) 1#时间复杂度的意义 2#基本操作执行次数 如 ...

  2. React Diff算法详解

    react diff算法 diff算法, 是 Virtual DOM 产生的一个概念, 用来计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面,从而提 ...

  3. svm 算法详解与推导

    前言 由于纸质笔记又臭又长(SVM这篇长达六张纸),可能字太难看完全没欲望于是把一些笔记整理到网上(公式可能太多),方便翻阅. 主要有这么个部分: 1. 函数间距.几何间距.软间距定义与区别. 2. ...

  4. 9. PKI - 三种密钥交换算法详解(RSA DHE ECDHE)及他们在SSL/TLS协议中的应用

    9. PKI - 三种密钥交换算法详解(RSA& DHE& ECDHE)及他们在SSL/TLS协议中的应用 RSA密钥交换算法 DHE密钥交换算法 ECDHE密钥交换算法 参考 密钥交 ...

  5. Matlab人脸检测算法详解

    这是一个Matlab人脸检测算法详解 前言 人脸检测结果 算法详解 源代码解析 所调用函数解析 bwlabel(BW,n) regionprops rectangle 总结 前言 目前主流的人脸检测与 ...

  6. 图论-最短路Dijkstra算法详解超详 有图解

    整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...

  7. C++中的STL算法详解

    1.STL算法详解 STL提供能在各种容器中通用的算法(大约有70种),如插入.删除.查找.排序等.算法就是函数模板,算法通过迭代器来操纵容器中的元素.许多算法操作的是容器上的一个区间(也可以是整个容 ...

  8. 粒子群(pso)算法详解matlab代码,粒子群(pso)算法详解matlab代码

    粒子群(pso)算法详解matlab代码 (1)---- 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,C ...

  9. 基础排序算法详解与优化

    文章图片存储在GitHub,网速不佳的朋友,请看<基础排序算法详解与优化> 或者 来我的技术小站 godbmw.com 1. 谈谈基础排序 常见的基础排序有选择排序.冒泡排序和插入排序.众 ...

最新文章

  1. 怎样成为一个高手观后感
  2. matlab求xk符号解,matlab符号运算习题
  3. java 读取 远程文件_利用JAVA获取远程文件及使用断点续传 供学习者使用
  4. Hive架构及安装部署(远程数据库模式MySQL)
  5. win7 mysql 密码_笔记本win7系统下mysql忘记密码的最佳解决方法
  6. 我和小美的撸码日记(1)之软件也需靠脸吃饭,带您做张明星脸(附后台经典框架 DEMO 下载)...
  7. 苹果推出Find My Friends好友追踪iOS应用
  8. java安全密钥_Java安全性:密钥大小或默认参数非法?
  9. 开发中所使用的渠道(统计分析、分享、第三方登录、短信等)
  10. javascript 阮一峰入门教程
  11. linux aix试题,《aix-linux考试试题.xls》-支持高清全文免费浏览-max文档
  12. 三星s8 android版本,三星S8+官方国行版安卓9完整固件系统升级包:CHC-G9550ZCU3DSF2...
  13. 怎么从PDF中提取图片?教你简单的提取方法
  14. 基于Mendix的云上全流程透明性备品备件协同管理
  15. Please change your current directory to a writable directory outside of the MATLAB installation area
  16. [BZFZ友谊赛]火山喷发
  17. SysAdmim 必备:系统性能大牛 Brendan Gregg 分享的 Linux 性能工具
  18. pdf转ppt在线转换
  19. IC高级工程会议——DVCon中国2019欢迎您的论文投稿!
  20. 正负样本不均衡的解决办法

热门文章

  1. 深入了解const !!!
  2. Celery-4.1 用户指南: Periodic Tasks
  3. 伯禹 动手学深度学习 打卡12之 RNN 进阶
  4. Android Studio 教程
  5. redis事务处理:(error) EXECABORT Transaction discarded because of previous errors.
  6. luckywang1103的专栏的博客--内容很多,涉猎很广,很不错
  7. 浅谈: 计算机—JVM—Java线程—池
  8. springboot+Layui后台开发框架
  9. validate实现表单验证
  10. 正向代理,反向代理及XFF