这是个水题,也没有什么实际应用意义(费马素性测试对卡米歇尔数无效)。一些博客把这题归为labin-miller测试,这是有误的。
写博客是因为被数组折腾了下,本来想初始化筛素数,MLE了,老老实实暴搜(注意题目的定义,伪素数首先要不是素数),但是问题来了,既然已经暴搜得出他是不是素数了,测试素性的意义何在?
可能题目只是想练一下快速幂。
Pseudoprime numbers
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 11387 Accepted: 4913
Description
Fermat's theorem states that for any prime number p and for any integer a > 1, ap = a (mod p). That is, if we raise a to the pth power and divide by p, the remainder is a. Some (but not very many) non-prime values of p, known as base-a pseudoprimes, have this
property for some a. (And some, known as Carmichael Numbers, are base-a pseudoprimes for all a.)
Given 2 < p ≤ 1000000000 and 1 < a < p, determine whether or not p is a base-a pseudoprime.
Input
Input contains several test cases followed by a line containing "0 0". Each test case consists of a line containing p and a.
Output
For each test case, output "yes" if p is a base-a pseudoprime; otherwise output "no".
Sample Input
3 2
10 3
341 2
341 3
1105 2
1105 3
0 0
Sample Output
no
no
yes
no
yes
yes
#include<cstdio>
#include<cmath>
#define MAXN 1000000
#define ll long long
bool ispri(ll p)
{
if (p < 2)return 0;
ll m = ceil(sqrt(p*1.0));
for (ll i = 2; i<m; i++)
{
if (p%i == 0)return 0;
}
return 1;
}
ll fast_pow(ll a, ll b, ll p)
{
a %= p;
ll tmp = 1;
while (b)
{
if (b & 1)tmp = (tmp*a) % p;
b >>= 1;
a = (a*a) % p;
}
return tmp;
}
bool judge(ll a, ll p)
{
if (ispri(p))return 0;
if (fast_pow(a, p, p) != a)return 0;
return 1;
}
int main()
{
ll a, p;
while (scanf("%lld%lld", &p, &a) && p != 0)
{
bool flg = judge(a, p);
if (flg)printf("yes\n");
else printf("no\n");
}
return 0;
}