前置知識:
1.費馬小定理:ap−
1≡1(
modp
),
pa^\equiv 1 \pmod p,p
ap−1≡1
(mod
p),p
為質數,且a
aa不為p
pp倍數。
2.二次探測定理:
p
pp為素數,則x2≡
1(mo
dp
)x^2\equiv 1\pmod p
x2≡1(m
odp)
的解為:x1=
1,x2
=p−1
x_1=1,x_2=p-1
x1=1,
x2=
p−1。
演算法實現流程:
1.特判,當n
<
3n<3
n<
3直接特判,否則n
nn為偶數肯定不是。
2.顯然由1篩出來的情況n−1
n-1n−
1肯定是偶數了。
令p =n
−1=x
×2
cp=n-1=x\times 2^c
p=n−1=
x×2c
。3.接下來我們需要利用二次探測定理,選取乙個底數a
aa,然後先計算出a
pa^p
ap,這裡形式就變成了ap=
an−1
=ax×
2c=(
ax)2
ca^p=a^=a^=(a^x)^
ap=an−
1=ax
×2c=
(ax)
2c,然後我們需要迴圈判斷c
cc次,是否滿足二次探測定理。
令x =a
x(mo
dn),
y=
xx=a^x\pmod,y=x
x=ax(m
odn)
,y=x
每次x =x
×x(m
odn)
=x2(
modn
)x=x\times x\pmod=x^2\pmod
x=x×x(
modn
)=x2
(mod
n)然後特判:y2=
xy^2=x
y2=x
,當x =1
x=1x=
1時yy
y是否為1
11或n−1
n-1n−
1。然後一輪過後y=x
y=xy=
x,進入下一輪。
4.最後x=a
n−
1x=a^
x=an−1
,利用費馬小定理特判x=1
x=1x=
1即可。
通過多次測試,使隨機演算法的錯誤概率降到很小。
時間複雜度:o(k
log3
n)
o(klog^3n)
o(klog
3n),k
kk為測試次數。
例題:傳送門
#include
using
namespace std;
typedef
long
long ll;
const
int n=
1e3+
5,m=
2e4+
5,inf=
0x3f3f3f3f
,mod=
1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define pii pair
#define fi first
#define se second
#define pb push_back
ll qmul
(ll a,ll b,ll mod)
ll qmul1
(ll a,ll b,ll mod)
ll ksm
(ll a,ll n,ll mod)
return ans;
}ll d[8]
=;bool
fun(ll n)
if(x!=1)
return0;
}return1;
}int
main()
return0;
}
Miller Rabin素數測試
公尺勒拉賓素數測試 測試大素數的原基於 如果 n 是素數 且與a 互質 那麼則有 a n 1 1 mod n 這個和費馬小定理 a n a mod n 差不多 1 因此首先可以進行快速冪取模函式 qpow 2 先將y y n 1 的偶數倍先將其右邊為0 的部分去掉 然後進行快速冪求模 3 這裡求出的...
Miller Rabin 素數測試
miller rabin 是乙個基於小費馬定理的隨機演算法。先來介紹一下費小馬定理 費馬小定理 當 p 為質數,則有當 1 leqslant a leqslant p 1 時有 a equiv 1 mod p 可能是素數 然後介紹一下素數二次測試 如果 p 是素數 x 2 equiv 1 mod p...
素數判定 Miller Rabin 演算法
談到素數判定,首先想到的兩種便是暴力判定與篩法,實現非常簡單,在此不提。但在分解大質數時,由於數字過大,使得暴力判定會超時,篩法會超空間 可使用有技巧的限制空間篩法,但數字過大仍然過不了 這時,我們就要引入非完美大質數判定演算法 miller rabin演算法。下面一段引自sunshine cfbs...