费尔马小定理素数java_利用费马小定理判断素数
今天聽了ljss神犇的數論課,頓時感覺————我真的是太弱啦!
我只能稍微寫一下我能聽懂的部分orz
那么這就是今天我為數不多能聽懂一點的之一......QAQ
首先先介紹今天的主角:費馬小定理
————轉自維基百科
沒看懂的話我稍微解釋一下,就是
假如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}}}
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}}}
來源:https://www.cnblogs.com/tsunderehome/p/7517658.html
總結
以上是生活随笔為你收集整理的费尔马小定理素数java_利用费马小定理判断素数的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Java集合之Vector源码分析
- 下一篇: 课堂笔记——Ubiquitous Com
