关于素数的不到100个秘密

本文详细介绍了素数检验的各种方法,包括试除法、埃氏筛法、欧拉筛以及Miller-Rabin随机算法,并探讨了大数分解的奇淫技巧。同时,文中提及素数密度的概念及其在实际问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

拖更了一天,这感觉太Nice了。于是在几乎打算断更的情况下艰难地写下了这篇博客。
由于作者变懒了,今天没有好好学习,所以没有写欧拉筛的板子,也没有素数测试的板子,更没有大数分解的板子。但是我尽量都会提到他们。板子自寻吧,或者以后写了再补上。
如果作者遭遇不测断更后,读者不知道学什么了,请认真打游戏,好好享受生活。
 
 

素数的检验:

先讲一下什么是素数
现在介绍如何检验素数,按笔者的学习顺序来讲。
 
首先,最早认识的应该都是朴素o(n)o(\sqrt{n})o(n)的试除法。(这个不难,原理就不讲了)

bool isPrime(ll n)
{
    if(n==1)return false;
    for(ll i=2;i*i<=n;i++)if(n%i==0)return false;
    return true;
}

 
再后来,就是o(nlogn)o(nlogn)o(nlogn)的埃氏筛法,筛完可以o(1)o(1)o(1)检验。(这个也不难,原理就不说了)

notPrime[1]=1;
for(ll i=1;i<=n;i++)if(!notPrime[i])
{
    for(ll j=2*i;j<=n;j+=i)notPrime[j]=1;
}

这个筛法还有另一种运用,比如判断[a,b][a,b][a,b]内的素数,其中1<a<b<1e91<a<b<1e91<a<b<1e9b−a<1e5b-a<1e5ba<1e5。此时,我们可以先筛出b\sqrt{b}b范围内的所有素数,然后拿这些素数去筛这个区间,就可以得到答案了。

 
再后来,就是o(n)o(n)o(n)的欧拉筛,筛完也可以o(1)o(1)o(1)检验。

说来惭愧,作者不会手撕欧拉筛,加上今天没有好好学习。
由于过强的版权意识,作者没有去别的地方拉板子放这里。
等后面积性函数筛的时候一起补上。
这是一首藏头诗。

 
 
最后是MillerRabinMiller RabinMillerRabin的素数测试,在long long范围内也很受用。这是一个随机算法,进行多次检验,每次检验正确的概率大约是14\frac{1}{4}41,检验次数越多越准确,复杂度为o(t×logn)o(t\times logn)o(t×logn),其中ttt为检验次数。
不过毕竟是随机算法,在复杂度够的情况下,单次检验还是考虑o(n)o(\sqrt{n})o(n)的试除法更好。

稍微讲一下原理。
先说简单的费马素数测试。
根据费马小定理:当ppp为素数,且gcd(a,p)=1gcd(a,p)=1gcd(a,p)=1时,ap−1≡1(mod  p)a^{p-1}\equiv 1(mod\;p)ap11(modp)
那么,如果我们要判断的数ppp不满足这个条件,那它一定不是素数。
但是仅依据这个有很大的漏洞,因为费马小定理不是充要条件,充分性成立,但必要性不成立。
存在一些数满足充分条件,而不满足必要条件,这就是费马伪素数
因为他们的存在,使得这个检验方法有很大的问题。
 
但是费马素数测试可以判掉大部分数。那么我们要找另一种检测办法来进一步判断。
于是我们利用二次探测:若ppp为素数,则方程x2≡1(mod  p)x^{2}\equiv 1(mod\;p)x21(modp)的解为x=1x=1x=1x=p−1x=p-1x=p1
 
那么怎么利用呢,关键部分就来了,先罗列我们要做的几个事情。

  • 我们要随机一个数aaa
  • 要用aaa进行费马素数检验,看看ap−1≡1(mod  p)a^{p-1}\equiv 1(mod\;p)ap11(modp)是否成立。
  • 然后要进行二次探测,但是要解方程就麻烦了,不过我们现在有了ap−1≡1(mod  p)a^{p-1}\equiv 1(mod\;p)ap11(modp),所以我们只要看看ap−12a^{\frac{p-1}{2}}a2p1是否为111p−1p-1p1就好了。

到这里,我们又发现,进行费马素数测验要快速幂,而快速幂中又用到了ap−12a^{\frac{p-1}{2}}a2p1这样的东西。
那么就可以放在一起写了。
并且当ap−12a^{\frac{p-1}{2}}a2p1111时,又可以利用他进行一次二次探测;反之如果是p−1p-1p1就无法继续利用了。
这样子代码就可以写了。

我和我的祖国 一刻也不能分割
无论我走到哪里 都流出一首赞歌
我歌唱每一座高山 我歌唱每一条河
袅袅炊烟 小小村落 路上一道辙
我亲爱的祖国 我永远紧依着你的心窝
你用你那母亲的温情和我诉说
我的祖国和我 像海和浪花一朵
浪是海的赤子 海是那浪的依托
每当大海在微笑 我就是笑的旋涡
我分担着海的忧愁 分享海的欢乐
我亲爱的祖国 你是大海永不干涸
永远给我 碧浪清波 心中的歌
啦……啦……
永远给我 碧浪清波 心中的歌

那么,素数的检验办法就介绍完了。
 
 

因式分解:

首先,是传统o(n)o(\sqrt{n})o(n)的分解法,应该都会就不写了。
 
然后是跟素数测试一样的奇淫 技巧,大数分解。
复杂度可以实现o(n0.25)o(n^{0.25})o(n0.25),但是跟素数测试一样是随机算法,所以不太稳定,除非万不得已,否则要少用。原理我也还没看,就不写了。
代码如下:

至于代码,就像现在你看到的,也是没有的,不过网上板子还是一大堆。

 
 

素数密度:

又叫素数分布定理。大致意思就是说,两个相邻的素数不会相距太远,大概就是o(log2n)o(log^{2}n)o(log2n)级别的。1e91e91e9范围内的最大间距是比300300300小的(又或许250250250?)。(1e181e181e18范围内好像不超过500500500?)
具体应用的话还是可以见过好多次的,比如让你求小于n(2<n<1e9)n(2<n<1e9)n(2<n<1e9)的最大素数,有了这个定理之后,就可以暴力枚举判断了。
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值