关于素数的不到100个秘密

前言:

拖更了一天,这感觉太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 ( n l o g n ) 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 < 1 e 9 1<a<b<1e9 1<a<b<1e9 b − a < 1 e 5 b-a<1e5 ba<1e5。此时,我们可以先筛出 b \sqrt{b} b 范围内的所有素数,然后拿这些素数去筛这个区间,就可以得到答案了。

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

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

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

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

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

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

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

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

因式分解:

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

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

 
 

素数密度:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值