知识点简单总结——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();}

应用

不知道(?)

最新文章

  1. SSM 三大框架整合
  2. Linux使用汇总贴
  3. 哈希 poj 1480
  4. php递归函数--遍历
  5. Dom操作的分类
  6. ORACLE中大数据量查询实现优化
  7. com.sun.org.apache.commons.logging.LogConfigurationException: java.lang.NullPointerException
  8. OpenStack Summit Paris 会议纪要 - 11-04-2014
  9. Qt String 与char* char int之间的转换
  10. .NET Core 使用RSA算法 加密/解密/签名/验证签名
  11. SharePoint中你不知道的图片库(实战)
  12. 36.QT-解决无边框界面拖动卡屏问题(附带源码)
  13. 前后台得到WEB应用的名称
  14. nginx如何安装第三方模块
  15. Coursera, Deep Learning 2, Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization - week1, Course
  16. 使用CloneDB克隆数据库
  17. [leetcode]100. Same Tree相同的树
  18. 图片上传插件:webuploader
  19. [err]multiple definition of `***&#39;
  20. MessagePack 学习笔记

热门文章

  1. 基于XC7Z100+AD9361的双收双发无线电射频板卡
  2. Solution -「USACO 2020.12 P」Spaceship
  3. Solution -「ARC 104C」Fair Elevator
  4. EasyX库简单中文手册
  5. mysql5.7下载
  6. 信而泰IPv6协议一致性测试解决方案
  7. 8款国内外主流商业智能BI工具分析,助你轻松选型!
  8. Win10系统下关闭管理员运行确认弹窗
  9. Hadoop2.7.2源码编译过程
  10. docker入门-常用命令和网络