Pseudoprime numbers
题意
费马小定理指出,对于任何素数p和任何整数a>1,ap ≡a (mod p)。也就是说,如果a的p次幂除以p,余数是a。一些(但不是很多)非素数值p,如果存在整数a>1使得ap = a (mod p),则称p是以a为基的伪素数。(还有一些数被称为Carmichael数,对于所有满足GCD(a, n)=1的正整数a,都是以a为基的伪素数。)
给出2<p≤1000000000和1<a<p,确定p是不是以a为基的伪素数。
输入
输入包含若干测试用例,最后以"0 0"的一行表示结束。每个测试用例一行,给出p和a。
输出
对每个测试用例,如果p是基于a的伪素数,输出"yes";否则输出"no"。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
ll p,a;
ll QuickPow(ll x, ll N)
{
ll res = x;
ll ans = 1;
while(N)
{
if(N & 1)
{
ans = ans * res%p;
}
res = res * res%p;
N = N >> 1;
}
return ans%p;
}
bool prime(ll n)
{
if(n==2) return true;
for(ll i=2;i<=sqrt(1.0*n);i++)
if(n%i==0)
return false;
return true;
}
int main()
{
while(cin>>p>>a)
{
if(a==0&&p==0) break;
if(!prime(p)&&a==QuickPow(a,p))
printf("yes\n");
else
printf("no\n");
}
return 0;
}