发现自己竟然菜到不太会龟速乘,所以把 \(Miller-Rabin\) 算法所需要用到的算法全学了一遍……

龟速乘

龟速乘是一种 \(O(\log n)\) 的乘法计算方法。

考虑有时普通乘法取模会爆 \(long\ long\),因此我们考虑用类似快速幂的方式进行乘法运算。

int mul(int x,int y,int c){
x%=c,y%=c;
int re=0;
while(y){
if(y&1) re+=x,re-=(re>=c)?c:0;
x+=x,x-=(x>=c)?c:0,y>>=1;
}return re;
}

快速乘

快速乘是一种 \(O(1)\) 的乘法计算方法。

发现 \(long\ double\) 可以存储 \(10^{300}\) 的数,所以考虑使用 \(long\ double\) 进行乘法运算。我还没有遇到过出锅的情况。

int mul(int a,int b,int p){
return (a*b-(int)((long double)a/p*b)*p+p)%p;
}

\(Miller-Rabin\) 算法

哈,这玩意错的跟对的一样。

和快速幂求逆元一样,我们考虑费马小定理。

我们可以得到:

设 \(f(x)=a^{x-1}\bmod x\),则当 \(f(p)\ne 1\) 时,\(p\) 一定是合数;当 \(p\) 是质数时,\(f(p)=1\)。

但是正确率不是人类所能接受的,所以考虑优化。

考虑下面这个性质:

若 \(b^2\bmod p=1\),\(p\) 为质数,则 \(b-1|p\) 或 \(b+1|p\)。

这样我们就可以进行二次探测,正确率大大提高。

我们设用于测试的集合为 \(A\),则 \(A=\{2,3,5,7,11,13,17,19,23\}\) 时,对于 \(x\le 10^{18}\) 的情况,都可以正确判断 \(x\) 的素性。

int mr[9]={2,3,5,7,11,13,17,19,23};
int mul(int a,int b,int p){
return (a*b-(int)((long double)a/p*b)*p+p)%p;
}int qpow(int x,int y,int c){
int re=1;
while(y){
if(y&1) re=mul(re,x,c);
x=mul(x,x,c),y>>=1;
}return re;
}int check(int x,int md){
int c=md-1,mid=qpow(x,c,md);
if(mid!=1) return 0;
while(!(c&1)&&mid==1)
c>>=1,mid=qpow(x,c,md);
return (mid==1||mid==md-1);
}int miller_rabin(int x){
if(x<2) return 0;
if(x<=23){
for(int i=0;i<9;i++)
if(mr[i]==x) return 1;
return 0;
}for(int i=0;i<9;i++)
if(!check(mr[i],x)) return 0;
return 1;
}

\(ps.Pollard\ rho\) 不太懂,贴份模板题代码,先咕咕了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int k,n;
int mr[9]={2,3,5,7,11,13,17,19,23};
int mul(int a,int b,int p){
return (a*b-(int)((long double)a/p*b)*p+p)%p;
}int qpow(int x,int y,int c){
int re=1;
while(y){
if(y&1) re=mul(re,x,c);
x=mul(x,x,c),y>>=1;
}return re;
}int check(int x,int md){
int c=md-1,mid=qpow(x,c,md);
if(mid!=1) return 0;
while(!(c&1)&&mid==1)
c>>=1,mid=qpow(x,c,md);
return (mid==1||mid==md-1);
}int miller_rabin(int x){
if(x<2) return 0;
if(x<=23){
for(int i=0;i<9;i++)
if(mr[i]==x) return 1;
return 0;
}for(int i=0;i<9;i++)
if(!check(mr[i],x)) return 0;
return 1;
}int gcd(int x,int y){
return (!y)?x:gcd(y,x%y);
}int pr(int x){
int s=0,t=0,val=1;
int c=rand()%(x-1)+1;
for(int gl=1;;gl*=2,s=t,val=1){
for(int st=1;st<=gl;st++){
t=(mul(t,t,x)+c)%x;
val=mul(val,abs(t-s),x);
if(st%127==0){
int d=gcd(val,x);
if(d>1) return d;
}
}int d=gcd(val,x);
if(d>1) return d;
}
}void pol_rho(int x,int &mx){
if(x<=mx||x<2) return;
if(miller_rabin(x))
return mx=max(mx,x),void();
int p=x;while(p>=x) p=pr(x);
while(x%p==0) x/=p;
pol_rho(x,mx),pol_rho(p,mx);
}signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
srand(time(0));
cin>>k;
while(k--){
cin>>n;int ans=0;
pol_rho(n,ans);
if(ans==n) cout<<"Prime\n";
else cout<<ans<<"\n";
}return 0;
}

从龟速乘到 $Miller-Rabin$ 算法(数论算法总结)的更多相关文章

  1. 【docker】解决docker pull镜像 拉取镜像龟速的问题,docker拉取镜像使用阿里云docker镜像加速器

    在docker拉取mysql镜像过程中,出现龟速的问题,解决这个问题的方法: 这个页面 停留了好久好久,依旧没有下载完成. 碰上这种情况 1.先退出Ctrl+C 2.在浏览器上进入阿里云docker库 ...

  2. 国内jenkins搭建不再龟速的方式

    最新国内jenkisn搭建过程 第一步下载jenkins 点击进入清华源jenkins下载地址,我们下载的是jenkins-2.204.2.zip版本 之后解压后安装. 第二步配置管理员密码 自动弹出 ...

  3. 不再忍受龟速 Github,你也可以试试在云开发上部署个人博客!

    Hexo 是被大家广泛使用的静态博客系统, 除了在 Github Pages 部署以外,现在你有了一个新的选择,那就是使用云开发静态网站功能来部署啦! 云开发(CloudBase)是一款云端一体化的产 ...

  4. GMM算法k-means算法的比较

    1.EM算法 GMM算法是EM算法族的一个具体例子. EM算法解决的问题是:要对数据进行聚类,假定数据服从杂合的几个概率分布,分布的具体参数未知,涉及到的随机变量有两组,其中一组可观测另一组不可观测. ...

  5. 简单易学的机器学习算法——EM算法

    简单易学的机器学习算法——EM算法 一.机器学习中的参数估计问题 在前面的博文中,如“简单易学的机器学习算法——Logistic回归”中,采用了极大似然函数对其模型中的参数进行估计,简单来讲即对于一系 ...

  6. 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)

    一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...

  7. 重新想象 Windows 8 Store Apps (31) - 加密解密: 哈希算法, 对称算法

    原文:重新想象 Windows 8 Store Apps (31) - 加密解密: 哈希算法, 对称算法 [源码下载] 重新想象 Windows 8 Store Apps (31) - 加密解密: 哈 ...

  8. Hash散列算法 Time33算法

    hash在开发由频繁使用.今天time33也许最流行的哈希算法. 算法: 对字符串的每一个字符,迭代的乘以33 原型: hash(i) = hash(i-1)*33 + str[i] ; 在使用时.存 ...

  9. 变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/mutating-algorithms.h ...

  10. STL非变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...

随机推荐

  1. mongo设置可选的唯一索引

    对于一些可能为空但必须唯一的字段,mongo支持创建部分索引,使用 partialFilterExpression 字段. MongoDB version >= 3.2 下面以 unique_a ...

  2. Winform在主窗体里切换多个窗体

    1.点击解决方案资源管理器的项目名称,右键添加用户控件(Windows窗体). 2.在主窗体代码中实例化添加的用户控件(Windows窗体). 点击查看代码 UserControl1 userCont ...

  3. 使用 Windows Debugger 调试托管代码

    使用 Windows Debugger 调试托管代码 https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugg ...

  4. 中电金信:金Gien乐道 | 4月要闻速览,精彩再回顾

    ​ 中国电子党组副书记.总经理李立功一行调研中电金信 ​ 4月10日,中国电子党组副书记.总经理李立功一行赴中电金信进行调研,深入听取了中电金信经营发展情况.研发工作及"源启"行业 ...

  5. jdk安装-windows和linux

    下载:见此博客https://www.cnblogs.com/zn19961006/p/12857930.html 一.windows安装 1.很简单,运行exe,然后一直下一步 选安装路径. 注意: ...

  6. @EnableWebMvc 注解会让Swagger无效访问的问题

    在工作中,通过Swagger2对项目的controller进行配置,以便于用户测试restful服务接口提高开发效率. 但是今天却出现了一个让我匪夷所思的问题就是在配置类里面加上@EnableWebM ...

  7. Qt开发经验小技巧156-160

    Qt的UI界面在resize以后有个BUG,悬停样式没有取消掉,需要主动模拟鼠标动一下. void frmMain::on_btnMenu_Max_clicked() { ...... //最大化以后 ...

  8. Qt开源作品21-日志重定向输出类

    一.前言 用qt开发商业程序已经十年了,陆陆续续开发过至少几十个程序,除了一些算不算项目的小工具外,大部分的程序都需要有个日志的输出功能,希望可以将程序的运行状态存储到文本文件或者数据库或者做其他处理 ...

  9. Qt编写的项目作品30-录音播放控件(雨田哥作品)

    一.功能特点 使用FMOD音频引擎开发,支持跨平台,虚拟频道,插件设计. 数字回放,多个声卡,多路输出,多路输入. 自定义回放延迟,网络特性. 支持类型:DLS.M3U.ASX.WAX.PLS.AIF ...

  10. vs 禁用c++编译警告提示的两种方式

    1. 禁用单个cpp文件编译警告 #pragma warning(disable:警告号) 如:当前提示C4305警告; 加入禁用单个cpp文件编译警告; 结果:编译警告消失. 2. 全局禁用指定警告 ...