利用费马小定理判断一个大整数是否为素数
这是一篇关于一个显而易见的结论的文章,请理解的同学不要水我。
大家应该都知道费马小定理是个啥:
其中a为整数且p为质数,在此就不证明了,对此感兴趣的同学可以去找下度娘。
到这里神犇的你显然理解了如何利用定理来判断素数了
当我们判断一个整数n的时候,可以枚举a判断定理是否成立,只要对于任何一个a定理不成立,n显然就不是素数
此法可以用来判断少量的较大的素数,大量的话请大家移步筛法。。。
但我们注意到,其逆定理不能直接用来判断素数,必须要枚举很多数,一般情况下我们可以枚举到1000左右,就可以把long long范围内的大部分数给判断完成。
也有例外,即存在一种极端反例卡迈克尔数(一种合数),对于任何a定理都成立。虽然这种极少,在1e8范围内的整数中,只有255个卡迈克尔数。但不管怎么说还是会被出题人卡死,或者被人hack,虽然这种算法的出错率为4^-k(k为测试数据的个数)。
而为了防止这种情况出现,有一种东西,叫二次探测定理:
如果p是奇素数,则 x≡1(mod p)的解为x=1或x=p-1(mod p),这个由模运算的性质易得。
这样的出错概率就会降到极低了(几乎不会出错)。
贴下代码:
1.裸快速幂模板
//快速幂实现(不含二次探测)
#include <bits/stdc++.h>
#define MAXTEST 50
using namespace std;
typedef long long ll;
ll fastpow(ll a,ll b,ll mod) //快速幂模板
{
ll r=1,base=a;
while(b){
if(b&1) {
r*=base;
r%=mod;
}
base*=base;
base%=mod;
b>>=1;<