Pollard_rho算法进行质因素分解要依赖于Miller_Rabbin算法判断大素数,没有学过的可以看一下,也可以当成模板来用

讲一下Pollard_rho算法思想:

求n的质因子的基本过程是,先判断n是否为素数,如果不是则按照一个伪随机数生成过程来生成随机数序列,对于每个生成的随机数判断与n是否互质,如果互质则尝试下一个随机数。如果不互质则将其公因子记作p,递归求解p和n/p的因子。如果n是素数则直接返回n为其素因子。

Pollard rho算法的原理就是通过某种方法得到两个整数a和b,而待分解的大整数为n,计算p=gcd(a-b,n),直到p不为1,或者a,b出现循环为止。然后再判断p是否为n,如果p=n成立,那么返回n是一个质数,否则返回p是n的一个因子,那么我们又可以递归的计算Pollard(p)和Pollard(n/p),这样,我们就可以求出n的所有质因子。

具体操作中,我们通常使用函数x2=x1*x1+c来计算逐步迭代计算a和b的值,实践中,通常取c为1,即b=a*a+1,在下一次计算中,将b的值赋给a,再次使用上式来计算新的b的值,当a,b出现循环时,即可退出进行判断。

在实际计算中,a和b的值最终肯定一出现一个循环,而将这些值用光滑的曲线连接起来的话,可以近似的看成是一个ρ型的。
对于Pollard rho,它可以在O(sqrt(p))的时间复杂度内找到n的一个小因子p,可见效率还是可以的,但是对于一个因子很少、因子值很大的大整数n来说,Pollard rho算法的效率仍然不是很好

为啥要取两个随机数的差?

对于一个大整数n,我们取任意一个数使得是的质因数的几率很小,但如果取两个数以及

使得它们的差是n的因数的几率就提高了,如果取x1以及x2使得gcd(abs(x1-x2), n) > 1的概率就更高了,这就是Pollard-Rho算法的思想。(概率的增加是因为组合数增加了)

为啥要用到Miller_Rabbin算法判断大素数

因为最后结果是n的所有质因子的乘积(这个乘积的形式只会有一种),那么肯定要判断某个数是不是素数,用Miller_Rabbin算法判断大素数判断的话要比普通方法快

代码:

  1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<map>
7 #include<vector>
8 #include<math.h>
9 #define mem(a,x) memset(a,x,sizeof(a))
10 using namespace std;
11 typedef long long LL;
12 const int maxn=50005;
13 const int mod=26;
14 const int INF=0x3f3f3f3f;
15 const int Times = 10;
16 const int N = 5500;
17 LL ct, cnt;
18 LL fac[N], num[N];
19 LL gcd(LL a, LL b) //求两数最大公因子
20 {
21 return b? gcd(b, a % b) : a;
22 }
23 LL multi(LL a, LL b, LL m) //快速乘
24 {
25 LL ans = 0;
26 a %= m;
27 while(b)
28 {
29 if(b & 1)
30 {
31 ans = (ans + a) % m;
32 b--;
33 }
34 b >>= 1;
35 a = (a + a) % m;
36 }
37 return ans;
38 }
39 LL pow(LL a, LL b, LL m) //快速幂
40 {
41 LL ans = 1;
42 a %= m;
43 while(b)
44 {
45 if(b & 1)
46 {
47 ans = multi(ans, a, m);
48 b--;
49 }
50 b >>= 1;
51 a = multi(a, a, m);
52 }
53 return ans;
54 }
55 bool Miller_Rabin(LL n) //判断n是不是素数
56 {
57 if(n == 2) return true;
58 if(n < 2 || !(n & 1)) return false;
59 LL m = n - 1;
60 int k = 0;
61 while((m & 1) == 0)
62 {
63 k++;
64 m >>= 1;
65 }
66 for(int i=0; i<Times; i++)
67 {
68 LL a = rand() % (n - 1) + 1;
69 LL x = pow(a, m, n);
70 LL y = 0;
71 for(int j=0; j<k; j++)
72 {
73 y = multi(x, x, n);
74 if(y == 1 && x != 1 && x != n - 1) return false;
75 x = y;
76 }
77 if(y != 1) return false;
78 }
79 return true;
80 }
81 LL pollard_rho(LL n, LL c) //大整数分解
82 {
83 LL i = 1, k = 2;
84 LL x = rand() % (n - 1) + 1;
85 LL y = x;
86 while(true)
87 {
88 i++;
89 x = (multi(x, x, n) + c) % n;
90 LL d = gcd((y - x + n) % n, n);
91 if(1 < d && d < n) return d;
92 if(y == x) return n;
93 if(i == k)
94 {
95 y = x;
96 k <<= 1;
97 }
98 }
99 }
100 void find(LL n, int c) //递归查找大整数n的质因子
101 {
102 if(n == 1) return;
103 if(Miller_Rabin(n))
104 {
105 fac[ct++] = n;
106 return ;
107 }
108 LL p = n;
109 LL k = c;
110 while(p >= n) p = pollard_rho(p, c--);
111 find(p, k);
112 find(n / p, k);
113 }
114 int main()
115 {
116 LL n;
117 while(cin>>n)
118 {
119 ct = 0;
120 find(n, 120);
121 sort(fac, fac + ct);
122 num[0] = 1;
123 int k = 1;
124 for(int i=1; i<ct; i++)
125 {
126 if(fac[i] == fac[i-1])
127 ++num[k-1];
128 else
129 {
130 num[k] = 1;
131 fac[k++] = fac[i];
132 }
133 }
134 cnt = k;
135 for(int i=0; i<cnt; i++)
136 cout<<fac[i]<<"^"<<num[i]<<" ";
137 cout<<endl;
138 }
139 return 0;
140 }

Pollard_rho算法进行质因素分解的更多相关文章

  1. Miller_Rabbin算法判断大素数,Pollard_rho算法进行质因素分解

    Miller-rabin算法是一个用来快速判断一个正整数是否为素数的算法.它利用了费马小定理,即:如果p是质数,且a,p互质,那么a^(p-1) mod p恒等于1.也就是对于所有小于p的正整数a来说 ...

  2. hdu 4497 GCD and LCM 质因素分解+排列组合or容斥原理

    //昨天把一个i写成1了 然后挂了一下午 首先进行质因数分解g=a1^b1+a2^b2...... l=a1^b1'+a2^b2'.......,然后判断两种不可行情况:1,g的分解式中有l的分解式中 ...

  3. 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case ...

  4. pollard_rho 算法进行质因数分解

    //************************************************ //pollard_rho 算法进行质因数分解 //*********************** ...

  5. 大数因式分解 Pollard_rho 算法详解

    给你一个大数n,将它分解它的质因子的乘积的形式. 首先需要了解Miller_rabin判断一个数是否是素数 大数分解最简单的思想也是试除法,这里就不再展示代码了,就是从2到sqrt(n),一个一个的试 ...

  6. 【转】大素数判断和素因子分解【miller-rabin和Pollard_rho算法】

    集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646 ...

  7. 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429

    素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: h ...

  8. 数学:随机素数测试(Miller_Rabin算法)和求整数素因子(Pollard_rho算法)

    POJ1811 给一个大数,判断是否是素数,如果不是素数,打印出它的最小质因数 随机素数测试(Miller_Rabin算法) 求整数素因子(Pollard_rho算法) 科技题 #include< ...

  9. 大素数判断和素因子分解(miller-rabin,Pollard_rho算法) 玄学快

    大数因数分解Pollard_rho 算法 复杂度o^(1/4) #include <iostream> #include <cstdio> #include <algor ...

随机推荐

  1. mac配置Android SDK

    下载地址:http://tools.android-studio.org/index.php/sdk 2.找到tools文件夹 选中android-sdk-macosx包下的tools文件夹,按com ...

  2. Mybatis的CRUD 增删改查

    目录 namespace 命名空间 select insert update delete Mybatis 官网: https://mybatis.org/mybatis-3/zh/getting-s ...

  3. 记忆中的像素块褪色了吗?用开源的体素编辑器重新做个 3D 的吧!

    本文适合对图形表现有兴趣的美术或者开发人员 本文作者:HelloGitHub-Joey 早期的的显示设备像素颗粒较大,使得显示内容的颗粒感严重,像是由一堆方块组成的.比较好的例子就是 GBA 上的游戏 ...

  4. 5V 升压 8.4V,5V 转 8.4V 做两节锂电池充电芯片

    5V 升压 8.4V SOT23-6 封装的六脚升压 IC PW5300 是一颗 DC-DC 异步整流升压转换器芯片,输入电压范围 2.6V-5.5V.最高输出 电压 12V, PW5300 是一种电 ...

  5. 解决JS获取中文参数出现的乱码问题

    在代码中增加如下js函数: function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + " ...

  6. 细数JS中实用且强大的操作符&运算符

    目录 1,前言 2,代码+应用 2.1,短路运算符 || 2.2,短路运算符 && 2.3,零合并操作符 ?? 2.4,可选链操作符 ?. 2.5,位运算符 & 和 | 2.6 ...

  7. centos7 centos-home 磁盘空间转移至centos-root下

    亲测可用,转载是为了记录,方便下次自己查看,如后朋友看到,请去查看作者原文,支持原创!!! 原文连接:https://www.cnblogs.com/renshengruxi/p/11782980.h ...

  8. VS2019中scanf返回值被忽略的问题及其解决方法

    目录 [问题](#昨天在使用Visual Studio 2019编写C语言程序时遇到了scanf返回值被忽略问题) 问题原因 方法① 方法② 方法③ 方法④ 昨天在使用Visual Studio 20 ...

  9. jemeter断言和性能分析

    一.添加断言 1.原因:检查是否有该结果,一般一个请求过去除了400和500的只要通过的都会代表请求成功,比如登录页面及时填写了错误密码,虽然会返回密码错误,但这个请求还是成功的,所以我们要添加断言, ...

  10. 策略模式 VS 状态模式

    策略模式 VS 状态模式 策略模式 VS 状态模式 | 菜鸟教程 https://www.runoob.com/w3cnote/state-vs-strategy.html