费尔马小定理素数java_利用费马小定理判断素数
今天聽了ljss神犇的數(shù)論課,頓時(shí)感覺(jué)————我真的是太弱啦!
我只能稍微寫一下我能聽懂的部分orz
那么這就是今天我為數(shù)不多能聽懂一點(diǎn)的之一......QAQ
首先先介紹今天的主角:費(fèi)馬小定理
————轉(zhuǎn)自維基百科
沒(méi)看懂的話我稍微解釋一下,就是
假如p是質(zhì)數(shù),且GCD(a,p)=1,那么 a^(p-1) ≡1(mod p)(假如p是質(zhì)數(shù),且a,p互質(zhì),那么 a的(p-1)次方除以p的余數(shù)恒等于1)
因此我們就似乎有了基于費(fèi)馬小定理的判斷素?cái)?shù)方式:隨機(jī)枚舉使gcd(a,p)=1的a。判斷該表達(dá)式是否成立--------記為命題q
但是仔細(xì)想一想,會(huì)發(fā)現(xiàn)命題q實(shí)際是費(fèi)馬小定理的逆命題
根據(jù)我們?cè)诟咧袛?shù)學(xué)選修2-1學(xué)習(xí)的內(nèi)容,真命題的逆命題不一定是真命題....
似乎出現(xiàn)了一些問(wèn)題呢x
所幸的是,這種思路大部分時(shí)間是正確的,因?yàn)楦鶕?jù)某個(gè)奇怪的性質(zhì),費(fèi)馬小定理只有對(duì)于少數(shù)數(shù)才會(huì)出現(xiàn)逆命題不成立的情況,而這類數(shù)就被稱為卡邁克爾數(shù)(Carmichael number)
卡邁克爾數(shù)在正整數(shù)中很少,并且隨著數(shù)的增大會(huì)變的越來(lái)越少,在1e8范圍內(nèi)只有255個(gè),1e17范圍內(nèi)也才只有不到6e5個(gè),因此可以直接多次應(yīng)用上述的算法來(lái)提高準(zhǔn)確性
不過(guò)作為有追求的oier,我們?cè)趺茨苓@么沒(méi)有夢(mèng)想呢?
我們引入新工具:
二次探測(cè)定理 如果p是一個(gè)素?cái)?shù),且0
下面給出簡(jiǎn)單的證明:
x^2≡1(mod p)
→x^2-1≡0(mod p)
→(x-1)(x+1)≡0(mod p)
那么我們將二次探測(cè)定理轉(zhuǎn)換成
(a(p-1)/2)2≡1(mod p)
應(yīng)用上面這兩個(gè)定理可以使失誤率達(dá)到最劣2-t,而實(shí)際遠(yuǎn)遠(yuǎn)達(dá)不到這個(gè)數(shù),因此一般3~5次即可保證正確性
該算法就是Miller_Rabin算法,期望復(fù)雜度O(tlog3n)
代碼:(還有些許唐突的地方,待補(bǔ)全)題目為洛谷線性篩模板
#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;
} //防止乘的時(shí)候過(guò)大爆掉
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;//隨機(jī)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}}}
a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
[a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
[a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
[a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
[a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
[a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
a p ? 1 ≡ 1 ( mod p ) {\displaystyle a^{p-1}\equiv 1{\pmod {p}}}
來(lái)源:https://www.cnblogs.com/tsunderehome/p/7517658.html
總結(jié)
以上是生活随笔為你收集整理的费尔马小定理素数java_利用费马小定理判断素数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java集合之Vector源码分析
- 下一篇: 课堂笔记——Ubiquitous Com