从龟速乘到 $Miller-Rabin$ 算法(数论算法总结)
发现自己竟然菜到不太会龟速乘,所以把 \(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$ 算法(数论算法总结)的更多相关文章
- 【docker】解决docker pull镜像 拉取镜像龟速的问题,docker拉取镜像使用阿里云docker镜像加速器
在docker拉取mysql镜像过程中,出现龟速的问题,解决这个问题的方法: 这个页面 停留了好久好久,依旧没有下载完成. 碰上这种情况 1.先退出Ctrl+C 2.在浏览器上进入阿里云docker库 ...
- 国内jenkins搭建不再龟速的方式
最新国内jenkisn搭建过程 第一步下载jenkins 点击进入清华源jenkins下载地址,我们下载的是jenkins-2.204.2.zip版本 之后解压后安装. 第二步配置管理员密码 自动弹出 ...
- 不再忍受龟速 Github,你也可以试试在云开发上部署个人博客!
Hexo 是被大家广泛使用的静态博客系统, 除了在 Github Pages 部署以外,现在你有了一个新的选择,那就是使用云开发静态网站功能来部署啦! 云开发(CloudBase)是一款云端一体化的产 ...
- GMM算法k-means算法的比较
1.EM算法 GMM算法是EM算法族的一个具体例子. EM算法解决的问题是:要对数据进行聚类,假定数据服从杂合的几个概率分布,分布的具体参数未知,涉及到的随机变量有两组,其中一组可观测另一组不可观测. ...
- 简单易学的机器学习算法——EM算法
简单易学的机器学习算法——EM算法 一.机器学习中的参数估计问题 在前面的博文中,如“简单易学的机器学习算法——Logistic回归”中,采用了极大似然函数对其模型中的参数进行估计,简单来讲即对于一系 ...
- 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)
一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...
- 重新想象 Windows 8 Store Apps (31) - 加密解密: 哈希算法, 对称算法
原文:重新想象 Windows 8 Store Apps (31) - 加密解密: 哈希算法, 对称算法 [源码下载] 重新想象 Windows 8 Store Apps (31) - 加密解密: 哈 ...
- Hash散列算法 Time33算法
hash在开发由频繁使用.今天time33也许最流行的哈希算法. 算法: 对字符串的每一个字符,迭代的乘以33 原型: hash(i) = hash(i-1)*33 + str[i] ; 在使用时.存 ...
- 变易算法 - STL算法
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/mutating-algorithms.h ...
- STL非变易算法 - STL算法
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...
随机推荐
- uniapp select组件
1.前言 官方的picker组件不能禁用某个下拉项,所以就有了这个下拉组件 组件只适配了宽屏模式,效果参照element-ui的select组件 demo地址:lianlizhou / ep-sele ...
- 【JS篇】控制子集超过一定数量开始轮播
[JS篇]控制子集超过一定数量开始轮播, 这个是很早的时候的一个效果了,经过代码的不断迭代升级修改,现在是最封装的一版本,通过面向对象传参数,适用于任何一个需要放置 数量达到一定条件后可执行的函数 / ...
- 【前端】‘opencollective-postinstall‘ 不是内部或外部命令,也不是可运行的程序
问题 'opencollective-postinstall' 不是内部或外部命令,也不是可运行的程序 解决办法 npm install --save opencollective-postinsta ...
- 19号CSS学习
一.CSS的复合选择器 更高效的选择目标元素. 后代选择器.子选择器.并集选择器.伪类选择器等. 1.后代选择器 可以选择父元素里的子元素. 又称包含选择器. 必须是空格,必须是后代,ul li {c ...
- 在分布式追踪系统中使用 W3C Trace Context
在分布式追踪系统中使用 W3C Trace Context https://dev.to/luizhlelis/using-w3c-trace-context-standard-in-distribu ...
- nginx-tengine-invalid IPv6 address in resolver-解析器中无效的IPv6地址
问题描述:解析器中无效的IPv6地址 [root@dm ~]# nginx -t nginx: [emerg] invalid IPv6 address in resolver "[fe80 ...
- 【Python】【Pandas】使用concat添加行
添加行 t = pd.DataFrame(columns=["姓名","平均分"]) t = t.append({"姓名":"小红 ...
- 详解AQS四:ReentrantLock条件队列原理
ReentrantLock的条件队列是实现"等待通知"机制的关键,之前在<java线程间通信:等待通知机制>一文中讲过了使用ReentrantLock实现多生产者.多消 ...
- java EE进行Web开发时*.jsp页面的<%@显示“The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path”错误,webcontent文件夹总是出现红x或者java源码出现The import javax.servlet cannot be resolved 的解决方法
我们在用Eclipse进行Java web开发时,可能会出现这样的错误:The superclass javax.servlet.http.HttpServlet was not found on t ...
- 深入Python胶水语言的本质:从CPython到各类扩展机制
在开始深入讲解Python如何作为胶水语言之前,我们需要先了解Python语言本身的实现机制.这对于理解Python如何与C语言交互至关重要. CPython:Python的默认实现 当我们谈论Pyt ...