知识点简单总结——Pollard-Rho算法

MillerRabin算法

用于对较大(int64)范围内的数判定质数。

原理:费马小定理,二次探测定理。

二次探测定理:若 $ p $ 为奇素数且 $ x ^ 2 \equiv1 ( mod \ p ) $ ,则 $ x \equiv \pm1(mod \ p) $ 。

选取多个素数 $ p $ 对要判断的数 $ x $ 进行测试:

首先进行费马小定理判断 $ x^{p-1} \equiv 1 (mod \ p) $ ,不是的话返回非。

之后设 $ k=p-1 $ 。当 $ k $ 是 $ 2 $ 的倍数时,将 $ k $ 除以 $ 2 $ ,继续计算 $ x^{k} \equiv \pm 1 (mod \ p) $ 。

不是的话返回非,否则如果结果为 $ 1 $ 且 $ 2 | k $ ,则继续重复操作,否则当 $ x^{k} \equiv -1 (mod \ p) $ 或 $ k $ 不再可除,无法继续用这个质数进行判定,返回真。

质数表随便打个,我用的 $ 2,3,7,19,61,24251 $ 。

Pollard-Rho算法

对于分解一个大合数 $ n $ ,考虑每次随机找到一个约数 $ c $ ,将 $ n/c $ 和 $ c $ 两部分递归处理。

随机一个初始变化率 $ d $ 和一个初始值 $ a_{0} $ ,每次 $ a_{i} = ( a_{i-1}^{2} +d ) mod \ n $ 。

每次求 $ gcd( | a_{i} - a_{0} | , n) $ ,如果结果不为 $ 1 $ 或 $ n $ ,那么证明分解出了一个约数。

$ a $ 最终会成环,期望长度 $ \sqrt{n} $ ,成环时更换变化率重新计算即可。

但依然需要继续优化。

考虑路径倍长,统计 $ s = \prod { | a_{i} - a_{0} | } $,每隔 $ 2^{k} $ 次将 $ s $ 一起gcd,之后将 $ a_{0} $ 设置为 $ a_{ k^{ 2 } } $ 。

#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef __int128 llint;
struct pat{int x,y;pat(int x=0,int y=0):x(x),y(y){}bool operator<(const pat &p)const{return x==p.x?y<p.y:x<p.x;}};
template<typename TP>inline void read(TP &tar)
{
TP ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
tar=ret*f;
}
namespace RKK
{
lint fpow(lint a,lint p,lint mo){lint ret=1;while(p){if(p&1ll) ret=(llint)ret*a%mo;a=(llint)a*a%mo,p>>=1;}return ret;}
lint gcd(lint a,lint b){return b?gcd(b,a%b):a;}
lint base[6]={2,3,7,19,61,24251};
bool mr(lint n,lint bas)
{
if(fpow(bas,n-1,n)!=1) return 0;
lint p=n-1;
while(!(p&1))
{
p>>=1;lint g=fpow(bas,p,n);
if(g==n-1) return 1;
else if(g!=1ll) return 0;
}
return 1;
}
bool mr(lint n)
{
if(n<2) return 0;
for(int i=0;i<6;i++)if(n==base[i]) return 1;
for(int i=0;i<6;i++)if(!mr(n,base[i])) return 0;
return 1;
}
lint pr(lint n)
{
int i=1,len=1;lint p=1,d=rand()%(n-1)+1,x=0,y=0;
while(1)
{
x=((llint)x*x+d)%n;
p=(llint)p*abs(x-y)%n;
if(!(i&127)){lint g=gcd(p,n);if(g>1) return g;}
if(i==len)
{
lint g=gcd(p,n);if(g>1) return g;
y=x,p=1,len<<=1,i=1;
}else i++;
}
}
vector<lint> ans;
void getfactor(lint n,vector<lint> &fac)
{
if(n==1ll) return;if(mr(n)){fac.push_back(n);return;}
lint p=n;while(p>=n) p=pr(n);
getfactor(p,fac),getfactor(n/p,fac);
}
int main()
{
int TAT;llint n;read(TAT);while(TAT--)
{
srand(time(NULL));
ans.clear();
read(n);getfactor(n,ans),sort(ans.begin(),ans.end());
if(ans.size()==1) puts("Prime");
else printf("%lld\n",ans[ans.size()-1]);
}
return 0;
}
}
int main(){return RKK::main();}

应用

不知道(?)

知识点简单总结——Pollard-Rho算法的更多相关文章

  1. Pollard Rho 算法简介

    \(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...

  2. Pollard Rho算法浅谈

    Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...

  3. Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

    BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][ ...

  4. 初学Pollard Rho算法

    前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...

  5. Miller Rabin素数检测与Pollard Rho算法

    一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...

  6. 大整数分解质因数(Pollard rho算法)

    #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...

  7. BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...

  8. 【快速因数分解】Pollard's Rho 算法

    Pollard-Rho 是一个很神奇的算法,用于在 $O(n^{\frac{1}4}) $的期望时间复杂度内计算合数 n 的某个非平凡因子(除了1和它本身以外能整除它的数).事书上给出的复杂度是 \( ...

  9. Miller-Rabin 素性测试 与 Pollard Rho 大整数分解

    \(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...

  10. 浅谈 Miller-Robbin 与 Pollard Rho

    前言 $Miller-Robbin$ 与 $Pollard Rho$ 虽然都是随机算法,不过用起来是真的爽. $Miller Rabin$ 算法是一种高效的质数判断方法.虽然是一种不确定的质数判断法, ...

随机推荐

  1. Spring Boot自动配置SpringMVC(二)

    Spring Boot自动配置SpringMVC(一) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)讲述了关于DispatcherServlet注册到诸如tomcat容器中的自动配置过 ...

  2. PentestBOX教程

    0x01 Pentest BOX Pentest Box:渗透测试盒子,是一款Windows平台下预配置的便携式开源渗透测试环境,而它也是著名黑客Kapustkiy常用的工具之一.这里集成的大都是Li ...

  3. .net框架的详解

    .net运行时 :Core,Xamarin,Mono或Framework? Core:面向所有平台 window .liniux .苹果mac .net Framework4.8:面向微软系统  已经 ...

  4. Pandas:loc iloc ix用法

    参考:Pandas中关于 loc \ iloc \ ix 用法的理解 相同点 使用形式都是 df.xxx[ para1 , para2 ] #xxx表示loc iloc ix#df表示一个DataFr ...

  5. c# 窗口不显示标题栏及周围有/无边框的设置

    一 : 不显示标题栏也无边框: 方法1:属性里直接设置 方法2:手写代码(两种效果一样) this.FormBorderStyle = FormBorderStyle.None; 二 : 不显示标题栏 ...

  6. 01-Servlet 回顾

    通过url访问资源有三个步骤: 接收请求 处理请求 响应请求 web服务器:将某个主机上的资源映射为一个URL供外界访问,完成接收和响应请求 servlet容器:存放着servlet对象(由程序员编程 ...

  7. [2022-2-18] OICLASS提高组模拟赛2 A·整数分解为2的幂

    题目链接 问题 A: 整数分解为 2 的幂 题目描述 任何正整数都能分解成 2 的幂,给定整数 N,求 N 的此类划分方法的数量!由于方案数量较大,输出 Mod 1000000007 的结果. 比如 ...

  8. 矩池云上使用Visdom可视化图像说明

    租用机器添加默认端口 点击展开高级选项 点击添加端口配置 添加Visdom默认端口,选择 http 端口填入 8097 进入环境安装并使用 JupyterLab 链接 是本次实验用来安装实验的工具 H ...

  9. PHP底层运行原理简括

    PHP是一种适用于web开发的动态语言.具体点说,就是一个用C语言实现包含大量组件模块的软件框架.是一个强大的UI框架. 简言之:PHP动态语言执行过程:拿到一段代码后,经过词法解析.语法解析等阶段后 ...

  10. 如何在Room框架下注册onUpgrade回调及自定义DatabaseErrorHandler

      在 Android 中,Room 为 SQLite 提供了高效稳定的抽象层,简化开发流程.RoomDatabase.java 是初始化数据库的重要构建组件,通过它我们可以添加RoomDatabas ...