Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9959 | Accepted: 4250 |
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与合数p,判断(a^p)%p是否等于a;
此题p值较大,若用O(n)的幂的计算方法会导致超时,此题采用快速幂。
快速幂为一种快速计算a^n次方的算法,以n=13为例,13转化为2进制后为1101,则a^13=a^(1+4+8)=a*a^4*a^8,又a^8=a^4*a^4,这样,我们就减少了许多计算量。
具体程序见下:
//By Sean Chen
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int isprime(long long x)
{
for (long long i=2;i*i<=x;i++)
if (x%i==0)
return 0;
return 1;
}
long long power(long long a,long long b) //快速幂
{
long long t=b;
long long ans=1;
long long base=a;
while (t>0)
{
if (t%2==1) //转2进制
ans=(ans*base)%b;
base=(base*base)%b;
t>>=1;
}
//cout<<ans<<endl;
return ans%b;
}
int main()
{
long long p,a;
while (scanf("%lld %lld",&p,&a) && p!=0 && a!=0)
{
if (isprime(p))
{
printf("no\n");
continue;
}
if (power(a,p)==a%p)
printf("yes\n");
else
printf("no\n");
}
return 0;
}