Pollard-Rho算法求大数质因子
/*
* 大整数分解到现在都是世界级的难题,但却是一个重要的研究方向,大整数在公共密钥的研究上有着重要的作用
* Pollard Rho算法的原理就是通过某种方法得到两个整数a和b.而待分解的大整数为n,计算p=gcd(abs(a-b),n),直到p不为1或者a,b出现循环为止.
* 然后再判断是否为n,如果p==n||p==1,那么返回n时一个质数
* 否则p就是n的一个因子
* 那么我们又可以递归地计算Pollard(p)和Pollard(n/p).
* 最后就可以推出n的所有质因子
*
* 具体操作中我们常常使用函数 x[i+1]=(x[i]*x[i]+c)%n 来逐步迭代计算a和b的值,通常c取1,即b=a*a+1,在下一次计算中,将b的值赋给a,再次使用上式来计算新的b的值,当a,b出现循环时即可退出判断.(初值自己确定)
* 但是这样的话判断循环比较麻烦,这里给出Floyd(没错又是他)发明的一个聪明而又有趣的算法:
* 假设我们在一个很长很长的圆形轨道上面行走,如何知道自己已经走了一圈了呢?
* 可以让两个人A和B按照 vb = va<<1 从同一起点开始向前走,当B第一次赶上A时,我们就知道B已经走了两圈
* 所以我们可以把x当作B,把y当作A,然后进行循环测试
*
* 对于Pollard Rho算法,它可以在O(sqrt(p))的时间复杂度内找到n的一个小因子p,可见效率还是可以的
* 但是对于一个因子很少或者因子值很大的大整数n来说,这个算法的复杂度依然不是很好
*/
//以下给出Pollard Rho和Miller-Rabin素数测试配合使用的整数分解算法
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
typedef long long ll;
const int counts = ,N = ; ll tot,cnt,fac[N],num[N]; ll gcd(ll a,ll b)
{return b?gcd(b,a%b):a;} ll qpow(ll a,ll x,ll p)
{
ll ret=;
for(;x;x>>=,a=a*a%p)
if(x&)
ret=ret*a%p;
return ret;
} ll multi(ll a,ll b,ll p)
{
ll ans=;
a%=p;
for(;b;b>>=,a=(a<<)%p)
if(b&)
ans=(ans+a)%p;
return ans;
} bool Miller_Rabin(ll n)
{
if(n==)return true;
if(n< || !(n&))return false;
ll m=n-,a,x,y;int k=;
while(!(m&))++k,m>>=;
for(int i=;i<counts;++i)
{
a=rand()%(n-)+;
x=qpow(a,m,n);
y=;
for(int j=;j<k;++j)
{
y=multi(x,x,n);
if(y== && x!=- && x!=n-)return false;
x=y;
}
if(y != -)return false;
}
return true;
} ll Pollard_Rho(ll n,ll c)
{
ll i=,k=,x=rand()%(n-)+,y=x,d;
while("fighting")
{
++i;
x=(multi(x,x,n)+c)%n;
d=gcd((y-x+n),n);
if(<d && d<n)return d;
if(y == x)return n;
if(i == k)y=x,k<<=;
}
} void find(ll n,int c)
{
if(n == )return ;
if(Miller_Rabin(n))
{
fac[tot++]=n;
return ;
}
ll p=n,k=c;
while(p>=n)p=Pollard_Rho(p,c--);
find(p,k);
find(n/p,k);
} int main()
{
ll n;
while(std::cin>>n)
{
tot=;
find(n,);
std::sort(fac,fac+tot);
num[]=;
int k=;
for(int i=;i<tot;++i)
{
if(fac[i] == fac[i-])
++num[k-];
else
{
num[k]=;
fac[k++]=fac[i];
}
}
cnt=k;
for(int i=;i<cnt;++i)
std::cout<<fac[i]<<"^"<<num[i]<<" ";
std::cout<<std::endl;
}
return ;
}
Pollard-Rho算法求大数质因子的更多相关文章
- cf 151 C. Win or Freeze (博弈 求大数质因子)
题目 题意: 给一个数N,两人轮流操作每次将N变为一个N的非1非自身的因数,第一个无法进行操作的人获胜问先手是否有必胜策略,如果有的话在第二行输出第一步换成哪个数,如果第一步就不能操作则输出0数据规模 ...
- Pollard Rho 算法简介
\(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
- Pollard Rho算法浅谈
Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...
- Java实现 蓝桥杯 算法提高 Monday-Saturday质因子
试题 算法提高 Monday-Saturday质因子 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 这个问题是个简单的与数论有关的题目,看起来似乎是"求正整数的所有质因子 ...
- 大整数分解质因数(Pollard rho算法)
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...
随机推荐
- JVM 参数调优配置
在 tomcat 配置文件 tomcat/bin/catalina.sh 中 配置 JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xss1024K -XX ...
- IDEA 2019 快捷键终极大全
常用的有fori/sout/psvm+Tab即可生成循环.System.out.main方法等boilerplate样板代码 . 例如要输入for(User user : users) 只需输入use ...
- C#关键字:访问修饰符
一.访问修饰符 访问修饰符有public.private.protected.internal和protected internal.它们是修饰在类型(类.接口.委托.结构和枚举)和类型成员(字段.属 ...
- Parameter 0 of method sqlSessionTemplate in org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration required a single bean, but 2 were found:
Parameter 0 of method orderSqlSessionFactory in com.config.MultipleDBConfig required a single bean, ...
- NMS的实现代码详解
NMS代码说明(来自Fast-RCNN) 个人觉得NMS包含很多框,其坐标为(x1,y1,x2,y2),每个框对应了一个score,我们将按照score得分降序,并将第一个最高的score的框(我们叫 ...
- Java自学-数组 增强型for循环
Java 中如何使用增强for循环 增强型for循环在遍历一个数组的时候会更加快捷 步骤 1 : 增强型for循环 注:增强型for循环只能用来取值,却不能用来修改数组里的值 public class ...
- aria2 ssl
https://github.com/q3aql/aria2-static-builds https://github.com/aria2/aria2/issues/781
- JavaScript克隆数组
/** * 克隆数组 * @param arr */ function cloneArray(arr){ var _arr=[]; for(var i=0;i<arr.length;i++){ ...
- Java 初始化块
初始化块是和成员变量.成员函数一个级别的.一般用于类的初始化,也可执行其他java代码,作用和构造函数相同. 创建对象时,初始化块在构造函数之前执行. 初始化块分为普通初始化块.静态初始化块. 普通初 ...
- ar 解压一个.a文件报错: xxx.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
Linux 使用终端指令 ar x /Users/apple/Desktop/libWC_LIB_SDKT.a解压一个文件 报错如图所示: 是因为该.a文件包含了多个cpu架构,比如armv7,ar ...