Pollard_rho算法进行质因素分解
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算法进行质因素分解的更多相关文章
- Miller_Rabbin算法判断大素数,Pollard_rho算法进行质因素分解
Miller-rabin算法是一个用来快速判断一个正整数是否为素数的算法.它利用了费马小定理,即:如果p是质数,且a,p互质,那么a^(p-1) mod p恒等于1.也就是对于所有小于p的正整数a来说 ...
- hdu 4497 GCD and LCM 质因素分解+排列组合or容斥原理
//昨天把一个i写成1了 然后挂了一下午 首先进行质因数分解g=a1^b1+a2^b2...... l=a1^b1'+a2^b2'.......,然后判断两种不可行情况:1,g的分解式中有l的分解式中 ...
- 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29046 Accepted: 7342 Case ...
- pollard_rho 算法进行质因数分解
//************************************************ //pollard_rho 算法进行质因数分解 //*********************** ...
- 大数因式分解 Pollard_rho 算法详解
给你一个大数n,将它分解它的质因子的乘积的形式. 首先需要了解Miller_rabin判断一个数是否是素数 大数分解最简单的思想也是试除法,这里就不再展示代码了,就是从2到sqrt(n),一个一个的试 ...
- 【转】大素数判断和素因子分解【miller-rabin和Pollard_rho算法】
集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646 ...
- 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429
素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: h ...
- 数学:随机素数测试(Miller_Rabin算法)和求整数素因子(Pollard_rho算法)
POJ1811 给一个大数,判断是否是素数,如果不是素数,打印出它的最小质因数 随机素数测试(Miller_Rabin算法) 求整数素因子(Pollard_rho算法) 科技题 #include< ...
- 大素数判断和素因子分解(miller-rabin,Pollard_rho算法) 玄学快
大数因数分解Pollard_rho 算法 复杂度o^(1/4) #include <iostream> #include <cstdio> #include <algor ...
随机推荐
- Linux学习笔记 | 常见错误之VMware启动linux后一直黑屏
方法1: 宿主机(windows)管理员模式运行cmd 输入netsh winsock reset 然后重启电脑 netsh winsock reset命令,作用是重置 Winsock 目录.如果一台 ...
- 虚拟机linux共享文件夹
linux共享文件夹问题 1. 初配置 2. 挂载 018.7.8 为了实现win7与VMware中linux文件夹共享很花费了一些时间,但终成正果 1. 初配置 虚拟机设置->选项->共 ...
- 【ORA】ORA-00257 archiver error. 错误的处理方法
今天连接数据库,结果报错,ora-00257查看 [oracle@exam oracle]$ oerr ora 00257 00257, 00000, "archiver error. Co ...
- Trollcave-suid提权
一 扫描端口 扫描开放端口:nmap -sV -sC -p- 192.168.0.149 -oA trollcave-allports 扫描敏感目录:gobuster dir -u http://19 ...
- Poj-P2533题解【动态规划】
本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/ 题目出处: http://poj.org/problem?id=2533 题目描述: 如果ai1 < ...
- git 基本命令和操作
设置全局用户名+密码 $ git config --global user.name 'runoob' $ git config --global user.email test@runoob.com ...
- vue3.0改变概况
一.slot API在render实现原理上的变化 二.全局API使用规范变化 三.Teleport添加 四.composition API变化 五.v-model变化
- JavaScript常用API
JavaScript常用API 节点属性 文档节点 事件监听.一出事件 获取元素方法
- Object level permissions support
django-guardian (1.1.1+) - Object level permissions support. Home - Django REST framework https://ww ...
- Win10家庭版Hyper-V出坑(完美卸载,冲突解决以及Device Guard问题)
本文链接:https://blog.csdn.net/hotcoffie/article/details/85043894 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附 ...