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;
}


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