由费马小定理
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1}\equiv1(\mod p)
ap−1≡1(modp),当
p
p
p为质数时成 y<p
立。但当
p
p
p不为质数时该定理不一定成立。
这里用二次探测去优化这个公式。
大概内容若有
y
2
≡
1
(
m
o
d
p
)
y^2\equiv 1(\mod p)
y2≡1(modp)其中
p
p
p为质数,
y
<
p
y
则有
y
=
1
y=1
y=1或
y
=
p
−
1
y=p-1
y=p−1
令
k
=
p
−
1
=
2
m
∗
n
k=p-1=2^m*n
k=p−1=2m∗n
则
(
a
n
)
2
m
≡
1
(
m
o
d
p
)
(a^{n})^{2^m}\equiv 1(\mod p)
(an)2m≡1(modp)
随机一个数
x
x
x去模拟公式中的
a
a
a。若
(
a
n
)
(
.
.
.
)
%
p
(a^n)^{(...)}\%p
(an)(...)%p不为1或者
(
a
n
)
u
%
p
=
1
,
(
a
n
)
(
u
+
1
)
%
p
=
p
−
1
(a^n)^u\%p=1,(a^n)^{(u+1)}\%p=p-1
(an)u%p=1,(an)(u+1)%p=p−1则它一定不是质数。
进行十次以上的探测可以很高的概率判断素数。
using ll = long long ;
ll mul(ll a,ll b,ll p){
ll r = 0;
while(b) {
if(1&b) r = (r + a) % p;
a = (a + a) % p;
b >>= 1;
}
return r;
}
ll mi(ll a, ll b, ll p){
ll r = 1;
while(b) {
if(1&b) r = mul(r, a, p);
a = mul(a, a, p);
b >>= 1;
}
return r;
}
mt19937 rnd(time(NULL));
bool check(ll n){
if(n == 1)return false;
if(n == 2 || n == 3)return true;
if(n + 1 & 1)return false;
ll k = n - 1;
int r = 0;
while(k + 1 & 1) {
k >>= 1;
r ++;
}
ll res, la = 0;
int cnt = 1;
while(cnt--) {
res = rnd() % (n - 1) + 1;
res = mi(res, k, n);
if(res == 1) continue;
la = res;
for(int i = 0; i < r; i++) {
assert(res >= 0 && res < n);
res = mul(res, res, n);
if(res == 1){
if(la != n - 1) return false;
break;
}
la = res ;
}
if(res != 1)return false;
}
return true;
}