卧薪尝胆,厚积薄发。
MillarRabin素性测试
Date: Mon Jul 02 21:20:27 CST 2018 In Category: 总结

一次探测

由费马小定理得当 $p$ 是质数且 $a$ , $p$ 互质时由 $a^{p-1}\equiv1(mod\ p)$ ,取前 $12$ 个素数做 $a$ 依次判断是否符合

二次探测

对质数 $p$ 方程 $x^2\equiv1(mod\ p)$ 只有 $1$ 和 $p-1$ ( $-1$ )两个解,由于已知 $a^{p-1}\equiv1$ ,求 $a^{\frac{p-1} 2}$ 的值,如果不是 $1$ 或 $p-1$ ,则是合数。如果是,计算 $a^{\frac{p-1} 4}$ 直到指数是奇数。

特判

$1$ , $2$ ,还有就是测试的质数的情况。

代码


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,m;
inline ll read()
{
register ll res = 0;
register char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res;
}
ll prime[12] = {2ll,3ll,5ll,7ll,11ll,13ll,17ll,19ll,23ll,29ll,31ll,37ll};
inline ll mul(ll a,ll b,ll mod)
{
register ll res = 0ll;
a %= mod;
while(b)
{
if(b & 1)res = (res + a) % mod;
a = (a << 1) % mod;
b = b >> 1;
}
return res;
}
inline ll power(ll a,ll b,ll mod)
{
register ll res = 1ll;
a %= mod;
while(b)
{
if(b & 1ll)res = mul(res,a,mod);
b = b >> 1;
a = mul(a,a,mod);
}
return res;
}
bool check(ll a,ll b,ll mod)
{
if((b & 1) == 1)return true;
register ll t = power(a,(b >> 1),mod);
if(t == 1ll)return check(a,(b >> 1),mod);
else if(t == mod - 1ll)return true;
else return false;
}
inline bool test(ll k)
{
if(k == 1)return false;
if(k == 2ll)return true;
if((k & 1ll) == 0)return false;
for(register int i = 0;i < 9;++i)
{
if(prime[i] == k)return true;
else if(power(prime[i],k - 1ll,k) != 1ll)return false;
else if(!check(prime[i],k - 1ll,k))return false;
}
return true;
}
int main()
{
n = read();m = read();
for(register int i = 1;i <= m;++i)
{
if(test(read()))puts("Yes");
else puts("No");
}
return 0;
}
In tag:
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡