Time Limit: 1000MS | Memory Limit: 65536K | |
Total 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-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
Source
题意:
费马定理表述,对所有的素数p,对于任意一个数a ,都必定有ap = a (mod p),也就是ap 和a 在对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; }