Pollard-rho的质因数分解
思路:见参考文章(原理我是写不粗来了)
代码:
#include <iostream>
#include <time.h>
#include <map>
using namespace std;
long long an[] = {,,,,,,,};
map<long long,int> mp;//存因数和对应出现次数
int num = ;
long long Random(long long n)//生成0到n之间的整数
{
return (double) rand()/RAND_MAX*n+0.5;//(doubel)rand()/RAND_MAX生成0-1之间的浮点数
} long long q_mod(long long a,long long n,long long p)//快速幂
{
a = a%p;
//首先降a的规模
long long sum = ;//记录结果
while(n)
{
if(n&)
{
sum = (sum*a)%p;//n为奇数时单独拿出来乘
}
a = (a*a)%p;//合并a降n的规模
n /= ;
}
return sum;
} long long q_mul(long long a,long long b,long long p)//大数模
{
long long sum = ;
while(b)
{
if(b&)//如果b的二进制末尾是零
{
(sum += a)%=p;//a要加上取余
}
(a <<= )%=p;//不断把a乘2相当于提高位数
b >>= ;//把b右移
}
return sum;
} //Miller-Rabin
bool witness(long long a,long long n)
{
long long d = n-;
long long r = ;
while(d%==)
{
d/=;
r++;
}//n-1分解成d*2^r,d为奇数
long long x = q_mod(a,d,n);
//cout << "d " << d << " r " << r << " x " << x << endl;
if(x==||x==n-)//最终的余数是1或n-1则可能是素数
{
return true;
}
while(r--)
{
x = q_mul(x,x,n);
if(x==n-)//考虑开始在不断地往下余的过程
{
return true;//中间如果有一个余数是n-1说明中断了此过程,则可能是素数
}
}
return false;//否则如果中间没有中断但最后是余数又不是n-1和1说明一定不是素数
}
bool miller_rabin(long long n)
{
const int times = ;//试验次数
if(n==)
{
return true;
}
if(n<||n%==)
{
return false;
}
for(int i = ;i<times;i++)
{
long long a = Random(n-)+;//1到(n-1)
//cout << a << endl;
if(!witness(a,n))
{
return false;
}
}
return true;
} //求gcd
long long gcd(long long a,long long b)
{
return b==?a:gcd(b,a%b);
} //Pollard-rho
long long Pollard_rho(long long n,long long c)
{
//cout << "n " << n << " c " << c << endl;
long long i = ,k = ;
long long x = Random(n-)+;
long long y = x;
while(true)
{
i++;
x = (q_mul(x,x,n)+c)%n;
long long d = gcd(y-x,n);
if(<d&&d<n)
{
return d;
}
if(x==y)
{
return n;
}
if(i==k)
{
y = x;
k<<=;
}
}
}
void find(long long n,long long c)
{
if(n==)//找完了
{
return;
}
if(miller_rabin(n))//找到了质数
{
num++;
mp[n]++;
return;
}
long long p = n;
while(p>=n)//找p的因数
{
p = Pollard_rho(p,c--);//返回p的因数或1或本身
}
find(p,c);//递归地找p的因子
find(n/p,c);
}
int main()
{
long long n;
while(cin >> n)
{
num = ;
mp.clear();
find(n,);//随机选取的c
cout << n << " = ";
if(mp.empty())
{
cout << n << endl;
}
for(auto ite = mp.begin();ite!=mp.end();ite++)
{
cout << ite->first << "^" << ite->second;
auto i = ite;
if(++i!=mp.end()) //如果不是最后一个
{
cout << "*";//输出乘号
}
}
}
return ; }
其他分解质因数的方法:
朴素算法:枚举从2到n找n的因子,找到了就不断除,除到不能除为止,再找下一个因子。
为什么保证是素因子,从二开始,假设有二的因子,不断地除直到没有二就能保证二的倍数也没有了。类似于素数筛的思想。
代码:
map<int,int> mp;
void decom1(int n)
{
for(int i = ;i<=n;i++)
{
while(n%i==)
{
mp[i]++;
n /= i;
}
}
}
参考文章:
StanleyClinton,大数因数分解Pollard_rho 算法详解,https://blog.csdn.net/maxichu/article/details/45459533

陶无语,Pollard Rho因子分解算法,https://www.cnblogs.com/dalt/p/8437119.html(讲解原理的多一点,不过至于是否容易理解,嘿嘿)
Pollard-rho的质因数分解的更多相关文章
- POJ 1811 Prime Test (Pollard rho 大整数分解)
题意:给出一个N,若N为素数,输出Prime.若为合数,输出最小的素因子.思路:Pollard rho大整数分解,模板题 #include <iostream> #include < ...
- Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...
- 整数(质因子)分解(Pollard rho大整数分解)
整数分解,又称质因子分解.在数学中,整数分解问题是指:给出一个正整数,将其写成几个素数的乘积的形式. (每个合数都可以写成几个质数相乘的形式,这几个质数就都叫做这个合数的质因数.) .试除法(适用于范 ...
- Pollard Rho大质数分解学习笔记
目录 问题 流程 代码 生日悖论 end 问题 给定n,要求对n质因数分解 普通的试除法已经不能应用于大整数了,我们需要更快的算法 流程 大概就是找出\(n=c*d\) 如果\(c\)是素数,结束,不 ...
- HDU 3864 D_num Miller Rabin 质数推断+Pollard Rho大整数分解
链接:http://acm.hdu.edu.cn/showproblem.php? pid=3864 题意:给出一个数N(1<=N<10^18).假设N仅仅有四个约数.就输出除1外的三个约 ...
- 大整数分解质因数(Pollard rho算法)
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- 质因数分解的rho以及miller-rabin
一.前言 质因数分解,是一个在算法竞赛里老生常谈的经典问题.我们在解决许多问题的时候需要用到质因数分解来辅助运算,而且质因数分解牵扯到许许多多经典高效的算法,例如miller-rabin判断素数算法, ...
- POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)
题意:给出a和b的gcd和lcm,让你求a和b.按升序输出a和b.若有多组满足条件的a和b,那么输出a+b最小的.思路:lcm=a*b/gcd lcm/gcd=a/gcd*b/gcd 可知a/gc ...
- [学习笔记] Miller-Rabin质数测试 & Pollard-Rho质因数分解
目录 Miller-Rabin质数测试 & Pollard-Rho质因数分解 Miller-Rabin质数测试 一些依赖的定理 实现以及正确率 Pollard-Rho质因数分解 生日悖论与生日 ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
随机推荐
- js:如何在iframe重载前执行特定动作
问题说明: 点击左侧菜单时,右侧页面中的iframe加载菜单内容,在iframe加载的页面A中使用了websocket.点击其它菜单时,无法主动关闭websocket, 可能会造成websocket链 ...
- fidder配置 https设置 手机客户端
1.APP抓包时的手机代理设置: 让手机和PC在同一个局域网下面: 1.如果PC是笔记本,让iOS或Android手机.iPhone或笔记本它们连接同一个wifi网络即可(自己试了不行,未找到原因). ...
- [IISNode] 如何在IIS7/8下,配置一个可以通过IIS访问NodeJS的web项目
参考了一下几篇很给力的文章,在每篇文章中,都学到了解决遇到的问题的答案: (1)用iisnode模块,让你的Node.js应用跑在Windows系统IIS中 (2)让IIS能够运行Nodejs (3) ...
- [转]System Verilog的概念以及与verilog的对比
原文地址: http://blog.csdn.net/gtatcs/article/details/8970489 SystemVerilog语言简介 SystemVerilog是一种硬件描述和验证语 ...
- Vue脚手架菜鸟级错误 npm run dev
ERROR Failed to compile with 1 errors Failed to resolve loader: stylus-loaderYou may need to install ...
- MAC——Homebrew介绍和使用
一.Homebrew是什么 Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装.卸载.更新.查看.搜索等很多实用的功能.简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径 ...
- 解决 plsql 启动报错 Initialization error
由于文件 oci.dll 路径没添加 1.点击edit 2.点击PL/SQL 3.弹框中 填写oci.dll文件的完整路径!完整路径!完整路径!完整路径!完整路径!完整路径!完整路径!完整路径 ...
- Highcharts 宽度溢出容器
1,设置Highcharts的动态宽高. 获取Highcharts图表需要的宽高值,给到Highcharts图表的div容器. 如:var hpvCountSendDateHei = $(" ...
- VMware和Centos安装
1.Windows,VMware和Centos三者的关系 2.VMware安装 下载好之后一直下一步安装,很简单 3.Centos安装 打开VMware,点击创建新的虚拟机 选择自定义,然后点下一步 ...
- 【题解】Luogu P5341 [TJOI2019]甲苯先生和大中锋的字符串
原题传送门 实际按照题意模拟就行 我们先求出字符串的sa 因为要在字符串中出现k次,所以我们枚举\(l,r(r-l+1=k)\)看一共有多少种合法的方案 合法方案的长度下界\(lb\)为\(Max(h ...