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 ...
随机推荐
- 【Spring Cloud学习之五】配置中心
环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 一.什么是配置中心在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实 ...
- CentOS7 初始化硬盘分区、挂载、重启自动挂载
挂载硬盘设备到本地有一下步骤: 1.通过fdisk -l命令,查看硬盘信息 可以看到有两块磁盘/dev/vda和/dev/vdb vda是系统盘,vdb使我们新增的数据盘,在上图中其实已经挂载完成(设 ...
- 百度URL参数解析
在用Python爬取百度搜索的内容时,发现百度搜索的url非常的长,往往会跟一大段的参数,但其实很多参数都是没有必要的,如同样是搜索java关键字,可以通过 http://www.baidu.com/ ...
- Git 配置环境
安装 在Fedora/CentOS下安装 $ sudo yum install git 在Debian/Ubuntu Linux下载安装 $ sudo apt-get install git Wind ...
- c#中特性Attribute
接上篇: 特性介绍: 特性是一个类,需要间接或者直接继承Attribute父类,在标记特性时以中括号包裹,可以标记在元素之前.AttributeTargets.Class设置标记的元素,需要明确指定标 ...
- Python实现字典树
字典树,又称单词查找树,Trie 树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串 ...
- PLC采集与控制,实现MES工序管理与品质管控,记录产品的加工数据,工厂生产装配流水线的一次成功应用
1.通过程序与PLC的采集与控制,实现MES工序管理,品质管控,历史数据追溯的目的 2.大概的流程图 3.有三个地方相关联来实现以上功能,首先是MES的工序管理,设置指定的产品有那些工序,上位机程序扫 ...
- ubuntu 安装和配置 GitLab
一.概述 GitLab 是一个基于 Web 的开源 Git 软件仓库管理器,用 Ruby 编写,包括 wiki,问题管理,代码审查,监控以及持续集成和部署.它使开发人员能够创建,审查和部署他们的项目. ...
- python_socket (套接字)
socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的. 网络上两个程序通过一个双向的通信连接实现数据的交换,这个连接 ...
- Go ---- defer 和 return 执行的先后顺序
Go 中 defer 和 return 执行的先后顺序 多个defer的执行顺序为“后进先出”: defer.return.返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入 ...