Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9896 | Accepted: 4218 |
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
判断给出的 a 是不是一个合数, 如果是, 判断 ap = a (mod p) 是否成立。
素性判断,快速幂
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
//素性判断
bool isprime(ll x)
{
for(ll i= 2; i <= x/i; i++)
if(x % i == 0) return false;
return true;
}
//快速幂
bool quick_power(ll a, ll p)
{
ll power = 1, temp = a, exponent = p;
while(exponent > 0)
{
if(exponent & 1) power = power * temp % p;
temp = temp * temp % p;
exponent = exponent >> 1;
}
return power == a;
}
int main ()
{
ll p, a;
while(1)
{
scanf("%lld %lld", &p, &a);
if(p == 0 && a == 0) break;
bool f;
f = isprime(p) ? false : quick_power(a, p);
if(f) puts("yes");
else puts("no");
}
return 0;
}