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 ...
随机推荐
- JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.
JobStorage.Current property value has not been initialized. You must set it before using Hangfire Cl ...
- javascript异步上传压缩图片并立即显示图片
javascript异步上传压缩图片并立即显示图片<pre><!doctype html><html><head><meta charset=&q ...
- STL源码剖析——序列式容器#4 Stack & Queue
Stack stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口,元素的新增.删除.最顶端访问都在该出口进行,没有其他位置和方法可以存取stack的元素. ...
- BJFU-216-基于链式存储结构的图书信息表的修改
#include<stdio.h> #include<stdlib.h> #define MAX 100 typedef struct Book{ double no; cha ...
- day14——装饰器
day14 装饰器 装饰器本质就是闭包 开放封闭原则: 扩展是开放的(增加新功能),对源码是封闭的(修改已经实现的功能) 装饰器:用来装饰的工具 作用:在不改变源代码及调用方式的基础下额外增加新的功能 ...
- Linux目录结构(目录结构详解是重点)
1.Linux目录与Windows目录对比 1.Windows目录结构 2.Linux目录结构 深刻理解Linux 树状文件目录是非常重要的,只有记住他们,你才能在命令行中任意切换,想去哪里去哪里 2 ...
- Go基础编程实践(二)—— 类型转换
bool to string strconv包的FormatBool函数用于将bool转为string package main import ( "fmt" "strc ...
- LOJ #3103. 「JSOI2019」节日庆典
题意 给定字符串 \(S\) ,对于 \(S\) 的每个前缀 \(T\) 求 \(T\) 所有循环同构串的字典序最小的串,输出其起始下标.(如有多个输出最靠前的) \(|S| \le 3 \times ...
- redis 5.0 CLUSTERDOWN The cluster is down
安装 redis 集群,设置值报错,错误信息:redis 5.0 CLUSTERDOWN The cluster is down. 这个是由于安装错误导致的,需要重新进行 修复一下. 命令如下: [ ...
- 在Centos7中创建.net core 项目,并用Apache做代理服务器部署.net core项目
这一篇实例记录一次用Centos7创建并部署.net core项目的过程,希望能帮到用到的小伙伴. Kestrel 是 ASP.NET Core 项目模板中包括的默认 Web 服务器,Kestrel可 ...