POJ 3641 Pseudoprime numbers【素数+快速幂】

来源:互联网 发布:linuxmint优化 编辑:程序博客网 时间:2024/05/16 00:27

Pseudoprime numbers
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 8291 Accepted: 3471

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-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 210 3341 2341 31105 21105 30 0

Sample Output

nonoyesnoyesyes

Source

Waterloo Local Contest, 2007.9.23

题意:

费马定理表述,对所有的素数p,对于任意一个数a ,都必定有ap = a (mod p),也就是ap 和在对p 取模的情况下值是相同的,但是有一些数,被定义为 Pseudoprime numbers

因为他们对于基于某些a 值的情况下,费马定理是成立的,但是这个数本身不是素数,特别的,如果某个非素数对基于很多的a 都的都成立,这个数被定义为 Carmichael Numbers----以上都是在说定义...


然后给出两个数p,a 问p 是不是基于a 的Pseudoprime numbers...


题解:

由题意可知,需要满足两条,才能是Pseudoprime numbers

1,p 不是素数

2,ap = a (mod p)


第一条可以进行素性的测试,第二条可以进行快速幂取模运算


/*http://blog.csdn.net/liuke19950717*/#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;bool is_prime(ll n){if(n%2==0){return 0;}ll tp=sqrt(n*1.0+0.5);for(ll i=3;i<tp;i+=2){if(n%i==0){return 0;}}return 1;}ll quick_mod(ll n,ll m,ll mod){ll ans=1;while(m){if(m&1){ans=n*ans%mod;}n=n*n%mod;m>>=1;}return ans;}bool ok(ll p,ll a){return quick_mod(a,p,p)==a%p&&!is_prime(p);}int main(){ll p,a;while(scanf("%lld%lld",&p,&a),p|a){if(ok(p,a)){printf("yes\n");}else{printf("no\n");}} return 0;}


0 0