费尔马小定理素数java_利用费马小定理判断素数

本文介绍了如何利用费马小定理来判断素数,以及在面对逆命题可能不成立的情况时,通过二次探测定理改进的 Miller-Rabin 算法,该算法可以有效提高判断素数的准确性。文章提供了一个简单的 Java 代码实现,并讨论了算法的时间复杂度。
摘要由CSDN通过智能技术生成

今天听了ljss神犇的数论课,顿时感觉————我真的是太弱啦!

我只能稍微写一下我能听懂的部分orz

那么这就是今天我为数不多能听懂一点的之一......QAQ

首先先介绍今天的主角:费马小定理

4a1baefff049dabba227ef4c4301d496.png————转自维基百科

没看懂的话我稍微解释一下,就是

假如p是质数,且GCD(a,p)=1,那么 a^(p-1) ≡1(mod p)(假如p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1)

因此我们就似乎有了基于费马小定理的判断素数方式:随机枚举使gcd(a,p)=1的a。判断该表达式是否成立--------记为命题q

但是仔细想一想,会发现命题q实际是费马小定理的逆命题

根据我们在高中数学选修2-1学习的内容,真命题的逆命题不一定是真命题....

似乎出现了一些问题呢x

所幸的是,这种思路大部分时间是正确的,因为根据某个奇怪的性质,费马小定理只有对于少数数才会出现逆命题不成立的情况,而这类数就被称为卡迈克尔数(Carmichael number)

卡迈克尔数在正整数中很少,并且随着数的增大会变的越来越少,在1e8范围内只有255个,1e17范围内也才只有不到6e5个,因此可以直接多次应用上述的算法来提高准确性

不过作为有追求的oier,我们怎么能这么没有梦想呢?

我们引入新工具:

二次探测定理 如果p是一个素数,且0

下面给出简单的证明:

x^2≡1(mod p)

→x^2-1≡0(mod p)

→(x-1)(x+1)≡0(mod p)

那么我们将二次探测定理转换成

(a(p-1)/2)2≡1(mod p)

应用上面这两个定理可以使失误率达到最劣2-t,而实际远远达不到这个数,因此一般3~5次即可保证正确性

该算法就是Miller_Rabin算法,期望复杂度O(tlog3n)

代码:(还有些许唐突的地方,待补全)题目为洛谷线性筛模板

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define N 10000001

typedef long long ll;

const int inf=0x3fffffff;

const int maxn=2017;

using namespace std;

inline int read()

{

int f=1,x=0;char ch=getchar();

while(ch>'9'|ch

{

if(ch=='-')

f=-1;

ch=getchar();

}

while(ch<='9'&&ch>='0')

{

x=(x<<3)+(x<<1)+ch-'0';

ch=getchar();

}

return f*x;

}

ll qmulti(ll a,ll b,ll c)

{

ll tem=a,sum=0;

while(b)

{

if(b&1)sum=(sum+tem)%c;

tem=(tem+tem)%c;

b>>=1;

}

return sum;

} //防止乘的时候过大爆掉

ll qpow(ll a,ll b,ll c)

{

ll k=1;

while(b>0)

{

if(b&1)k=(k*a)%c;

a=(a*a)%c;

b>>=1;

}

return k;

}

bool witness(int a,int x,int k,int q)

{

ll v=qpow(a,q,x);

if(v==1||v==x-1)return 0;

while(k--)

{

v=v*v%x;

if(v==x-1)return 0;

}

return 1;

}

bool miller(ll n)

{

int time=5;//随机time次

if(n==2)return 1;//特判2

if(n<2||n%2==0)return 0;

ll a=0,t=0,b=n-1;

while(!(b&1))

{

t++;

b>>=1;

}

for(int i=0;i

{

a=rand()%(n-1)+1;

if(witness(a,n,t,b))return 0;

}

return 1;

}

int main()

{

srand(time(0));

ll n=read(),m=read();

for(ll i=1;i<=m;i++)

{

ll a=read();

printf(miller(a)?"Yes\n":"No\n");

}

}

a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688[a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688[a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688[a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688[a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688[a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688a p − 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}

5b71e80b05f598bfd9ac9618c87a94323e41e688

来源:https://www.cnblogs.com/tsunderehome/p/7517658.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值