在寒假的学习中,我们学习了数论相关知识,费马定理指出,对于任意的素数 p 和任意的整数 a > 1,满足 ap = a (mod p) 。然而,并不一定满足这个条件的都是素数。我们称p是基于a的伪素数当且仅当p不是素数,但是满足a^p=a(mod p)。
给定 2 < p ≤ 1000000000 且 1 < a < p ,判断 p 是否为以 a 为底的伪素数。
输入
输入包含多个测试用例,以 "0 0" 表示输入结束。每个测试用例,由包含 p 和 a 的一行组成。
输出
对于每个测试用例,如果 p 是以 a 为底的伪素数,则输出 "yes",否则输出 "no" 。
示例输入
3 2 10 3 341 2 341 3 1105 2 1105 3 0 0
示例输出
no no yes no yes yes
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
ll p, a;
bool isPrime(ll x) {
if(x < 2) return false;
for(ll i = 2; i <= x / i; i ++) {
if(x % i == 0) return false;
}
return true;
}
int main()
{
ios::sync_with_stdio(false);
while(cin >> p >> a && p + a) {
ll pp = p;
ll aa = a;
ll res = 1 % p;
while(p) {
if(p & 1) {
res = (res * a) % pp;
}
p >>= 1;
a = (a * a) % pp;
}
if(res == aa && !isPrime(pp)) cout << "yes" << "\n";
else cout << "no" << "\n";
}
return 0;
}