素数测试(判断素数)模板
1、素数测试:
#include<cstdlib>
#include<cstdio>
int modularExponent(int a, int b, int n) {
int ret = 1;
for (; b; b >>= 1, a = (int) ((long long) a * a % n)) {
if (b & 1) {
ret = (int) ((long long) ret * a % n);
}
}
return ret;
}
bool millerRabin(int n,int a) {
if (n == 1 || (n != 2 && !(n % 2)) || (n != 3 && !(n % 3)) || (n != 5 && !(n % 5)) || (n != 7 && !(n % 7))) {
return false;
}
int r = 0, s = n - 1, j;
if(!(n%a)) return false;
while(!(s&1)){ s >>= 1; r++; }
long long k = modularExponent(a, s, n);
if(k == 1) return true;
for(j = 0; j < r; j++, k = k * k % n)
if(k == n - 1) return true;
return false;
}
bool miller_Rabin(int n)//
{
int a[]={2,3,5,7},i;//能通过测试的最小素数为 3215031751(此数超int)
for(i=0;i<4;i++){
if(!millerRabin(n,a[i]))return false;
}
return true;
}
int main()
{
int n,x;
scanf("%d",&n);
while(n--){
scanf("%d",&x);
printf("%s\n",miller_Rabin(x)?"Yes":"No");
}
return 0;
}
#include<cstdlib>
#include<cstdio>
int modularExponent(int a, int b, int n) {
int ret = 1;
for (; b; b >>= 1, a = (int) ((long long) a * a % n)) {
if (b & 1) {
ret = (int) ((long long) ret * a % n);
}
}
return ret;
}
bool millerRabin(int n,int a) {
if (n == 1 || (n != 2 && !(n % 2)) || (n != 3 && !(n % 3)) || (n != 5 && !(n % 5)) || (n != 7 && !(n % 7))) {
return false;
}
int r = 0, s = n - 1, j;
if(!(n%a)) return false;
while(!(s&1)){ s >>= 1; r++; }
long long k = modularExponent(a, s, n);
if(k == 1) return true;
for(j = 0; j < r; j++, k = k * k % n)
if(k == n - 1) return true;
return false;
}
bool miller_Rabin(int n)//
{
int a[]={2,3,5,7},i;//能通过测试的最小素数为 3215031751(此数超int)
for(i=0;i<4;i++){
if(!millerRabin(n,a[i]))return false;
}
return true;
}
int main()
{
int n,x;
scanf("%d",&n);
while(n--){
scanf("%d",&x);
printf("%s\n",miller_Rabin(x)?"Yes":"No");
}
return 0;
}
3、查找小于等于MAXN的素数(生成连续素数表)
/*
* 素数筛选,查找出小于等于MAXN的素数
* prime[0]存素数的个数
*/
const int MAXN = 100000;
int prime[MAXN + 1];
void getPrime()
{
memset(prime, 0, sizeof(prime));
for (int i = 2; i <= MAXN; i++)
{
if (!prime[i])
{
prime[++prime[0]] = i;
}
for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++)
{
prime[prime[j] * i] = 1;
if (i % prime[j] == 0)
{
break;
}
}
}
}
4、大数素数测试
#define MAXL 4
#define M10 1000000000
#define Z10 9
const int zero[MAXL - 1] = {0};
struct bnum
{
int data[MAXL]; // 断成每截9个长度
// 读取字符串并转存
void read()
{
memset(data, 0, sizeof(data));
char buf[32];
scanf("%s", buf);
int len = (int)strlen(buf);
int i = 0, k;
while (len >= Z10)
{
for (k = len - Z10; k < len; ++k)
{
data[i] = data[i] * 10 + buf[k] - '0';
}
++i;
len -= Z10;
}
if (len > 0)
{
for (k = 0; k < len; ++k)
{
data[i] = data[i] * 10 + buf[k] - '0';
}
}
}
bool operator == (const bnum &x)
{
return memcmp(data, x.data, sizeof(data)) == 0;
}
bnum & operator = (const int x)
{
memset(data, 0, sizeof(data));
data[0] = x;
return *this;
}
bnum operator + (const bnum &x)
{
int i, carry = 0;
bnum ans;
for (i = 0; i < MAXL; ++i)
{
ans.data[i] = data[i] + x.data[i] + carry;
carry = ans.data[i] / M10;
ans.data[i] %= M10;
}
return ans;
}
bnum operator - (const bnum &x)
{
int i, carry = 0;
bnum ans;
for (i = 0; i < MAXL; ++i)
{
ans.data[i] = data[i] - x.data[i] - carry;
if (ans.data[i] < 0)
{
ans.data[i] += M10;
carry = 1;
}
else
{
carry = 0;
}
}
return ans;
}
// assume *this < x * 2
bnum operator % (const bnum &x)
{
int i;
for (i = MAXL - 1; i >= 0; --i)
{
if (data[i] < x.data[i])
{
return *this;
}
else if (data[i] > x.data[i])
{
break;
}
}
return ((*this) - x);
}
bnum & div2()
{
int i, carry = 0, tmp;
for (i = MAXL - 1; i >= 0; --i)
{
tmp = data[i] & 1;
data[i] = (data[i] + carry) >> 1;
carry = tmp * M10;
}
return *this;
}
bool is_odd()
{
return (data[0] & 1) == 1;
}
bool is_zero()
{
for (int i = 0; i < MAXL; ++i)
{
if (data[i])
{
return false;
}
}
return true;
}
};
void mulmod(bnum &a0, bnum &b0, bnum &p, bnum &ans)
{
bnum tmp = a0, b = b0;
ans = 0;
while (!b.is_zero())
{
if (b.is_odd())
{
ans = (ans + tmp) % p;
}
tmp = (tmp + tmp) % p;
b.div2();
}
}
void powmod(bnum &a0, bnum &b0, bnum &p, bnum &ans)
{
bnum tmp = a0, b = b0;
ans = 1;
while (!b.is_zero())
{
if (b.is_odd())
{
mulmod(ans, tmp, p, ans);
}
mulmod(tmp, tmp, p, tmp);
b.div2();
}
}
bool MillerRabinTest(bnum &p, int iter)
{
int i, small = 0, j, d = 0;
for (i = 1; i < MAXL; ++i)
{
if (p.data[i])
{
break;
}
}
if (i == MAXL)
{
// small integer test
if (p.data[0] < 2)
{
return false;
}
if (p.data[0] == 2)
{
return true;
}
small = 1;
}
if (!p.is_odd())
{
return false; // even number
}
bnum a, s, m, one, pd1;
one = 1;
s = pd1 = p - one;
while (!s.is_odd())
{
s.div2();
++d;
}
for (i = 0; i < iter; ++i)
{
a = rand();
if (small)
{
a.data[0] = a.data[0] % (p.data[0] - 1) + 1;
}
else
{
a.data[1] = a.data[0] / M10;
a.data[0] %= M10;
}
if (a == one)
{
continue;
}
powmod(a, s, p, m);
for (j = 0; j < d && !(m == one) && !(m == pd1); ++j)
{
mulmod(m, m, p, m);
}
if (!(m == pd1) && j > 0)
{
return false;
}
}
return true;
}
int main()
{
bnum x;
x.read();
puts(MillerRabinTest(x, 5) ? "Yes" : "No");
return 0;
}
5、判断小于MAXN得数是不是素数
/*
* 素数筛选,判断小于MAXN的数是不是素数
* notprime是一张表,false表示是素数,true表示不是
*/
const int MAXN = 1000010;
bool notprime[MAXN];
void init()
{
memset(notprime, false, sizeof(notprime));
notprime[0] = notprime[1] = true;
for (int i = 2; i < MAXN; i++)
{
if (!notprime[i])
{
if (i > MAXN / i) // 阻止后边i * i溢出(或者i,j用long long)
{
continue;
}
// 直接从i * i开始就可以,小于i倍的已经筛选过了
for (int j = i * i; j < MAXN; j += i)
{
notprime[j] = true;
}
}
}
}