這是個水題,也沒有什麼實際應用意義(費馬素性測試對卡米歇爾數無效)。一些博客把這題歸爲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;
}