3月2日 Pseudoprime numbers(費馬素性測試、卡米歇爾數、僞素數)

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章