基础数论算法(5) 素数的判定
来源:互联网 发布:软件代理合同范本 编辑:程序博客网 时间:2024/05/16 15:22
有关素数的研究很久之前就已经开始,根据科(xuan)学研究,数质数有助于睡眠。那么如何高效的让计算机数质数,跑得更快?这就是我们要探讨的主要内容。
O(n√ )判定法
数据比较小的时候,O(
实现:
bool isPrime(int x){ if(x<2) return false; for(int i=2;i*i<=m;i+=(i==2?1:2)) if(m%i==0) return false; return true;}
费马小定理判断法
有一个神奇的定理叫费马小定理。如果一个奇素数p,有
它的逆命题是错误的,但是如果我们rand()很多数出来带进逆命题检验,结果如何?事实证明,随机数目在1000次左右时,准确率可以达到99.7%左右。实现:
#include <bits/stdc++.h>using namespace std;typedef long long LL;int m[]={3,7,13,37,23};LL ksm(LL a,LL m,LL n){ if(m==0) return 1; if(m==1) return a%n; LL w=ksm(a,m>>1,n); w=w*w%n; if(m&1) w=w*a%n; return w;}bool fm(LL n){ if(n==2) return true; for(int i=0;i<5;++i){ int a=m[i]; if(ksm(a,n,n)!=a) return false; } return true;}int main(){ LL n; scanf("%d",&n); if(fm(n)) printf("Yes\n"); else printf("No\n"); return 0;}
我闲来无事将这个代码和直接判定对拍了一下,卡在了2821上。为什么呢?
有一类特殊的数:Carmichael数。这类数的特征是,对
因此,费马小定理测试得到了毁灭性打击。不过这仍然不失为一种容易实现的判断方法万一出题人卡这东西呢?说的好像因为出题人可能卡SPFA你就不用了似的为此而开发出的一种新的判断方法,就是Miller-Rabin测试。
Miller-Rabin测试法
即便对RP的需要有所下降,这仍然是一个拼RP的做法,但是你没有选择。因为这是最为快速且高效的判断法。
Miller-Rabin筛法基于Miller-Rabin定理。
Miler-Rabin定理
若n为素数,取a<n ,设n−1=d⋅2r ,
要么ad≡1(mod n) ,要么∃0⩽i⩽r,使ad⋅2i≡−1(mod n)
该定理的逆命题是不成立的,但是如果我们多取几个素数,逆命题正确的概率就会大大上升。与费马小定理不同之处是,MR定理不存在合数满足这一性质。
如果取的是2,3,5,7这四个,而在
代码参考了
https://github.com/Psycho7/Miller-Rabin/blob/master/CPP/Miller-Rabin.cpp
在下找了半天之后认为写的比较精悍的一个
#include <bits/stdc++.h>using namespace std;typedef long long LL;int pri[]={2,3,5,7,11,13,17};LL ksm(LL a,LL n,LL mod){ if(n==0) return 1; if(n==1) return a%mod; LL ans=1; while(n){ if(n&1) ans=(ans*a)%mod; a=a*a%mod; n>>=1; } return ans;}bool MR(LL x){ if(x==2) return true; if((x<2)||!(x&1)) return false; LL d=x-1; while(!(d&1))d>>=1; LL td,t; for(int i=0;i<7;++i){ if(pri[i]>=x) break; td=d; t=ksm(pri[i],td,x); while((td!=x-1)&&(t!=1)&&(t!=x-1)){ t=t*t%x; td<<=1; } if((t==x-1)||(td&1)) ; else return false; } return true; }int main(){ LL k; cin>>k; cout<<(MR(k)?"Yes":"No");}
说实话我是不太懂这个代码究竟是如何实现的,所以实在不行就先背会吧。
基本上相信自己的rp和出题人的良心的话跑费马小定理测试一般不会出问题,毕竟家里那本书在MR测试下堂而皇之的写着费马测试的代码,实在是不太想吐槽。当然,数据比较小的话,朴素算法也是没有什么问题的,关键是不容易出错,不要把8个TLE变成20个WA比什么都强。
复杂度的话,费马是O(klogn)的,MR是O(
- 基础数论算法(5) 素数的判定
- HDU 2012 素数判定(数论)
- 数论-素数判定
- 算法基础 - 素数判定(Miller-Rabin算法)
- 素数的Miller_Rabbin判定算法
- 模板:(数论:大素数判定-分解: Miller-Rabin算法)
- 质数(素数)判定算法
- 基础数论算法(六) 素数的筛法与质因数分解
- ACM:数论专题(1)——素数的判定
- 素数判定的一些讨论(Miller-Rabin算法)
- 一种素数判定算法的数学证明
- 浅谈基于随机性算法的素数判定
- 素数的判定(常规)
- 素数判定算法,紫书P194素数判定
- 素数判定随机化算法
- 素数判定算法
- 素数判定算法
- 素数判定算法小结
- nodejs微信公众号端口问题解决方案
- 对象&原型对象&原型链
- 在linux的终端怎么退出python命令行
- JAVA线程面试题书目录
- CSU 1578
- 基础数论算法(5) 素数的判定
- Spring IoC(控制反转)和DI(依赖注入)的理解
- Android Studio中使用opencv Library330
- Failed to replace env in config: ${APPDATA}
- 使用python builtwith模块分析识别网站开发技术
- 基于Baidu Map InfoWindow的消息交互(失败案例)
- c++中的类模板
- IIS 重定向配置
- H-Updating a Dictionary (模拟)