当前位置: 代码迷 >> 综合 >> POJ 3641 Pseudoprime numbers 快速幂+判断素数 快速幂模板
  详细解决方案

POJ 3641 Pseudoprime numbers 快速幂+判断素数 快速幂模板

热度:81   发布时间:2023-12-20 23:31:40.0

题目链接

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

题目大意:
给定 p 和 a,判断 p 是否为合数且满足 ap ≡ a(mod p)

解题思路:
判断素数+快速幂
注意,由于题目中p的范围过大,因此不能先进行素数筛法来筛选素数

快速幂模板代码:

ll mod_pow(ll x, ll n, ll mod) {
    ll res = 1;while (n > 0) {
    if (n & 1) res = res*x%mod;x = x*x%mod;n >>= 1;}return res;
}

AC代码:

#include<iostream>
#include<stdio.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e9 + 5;
bool Prime(ll t) {
    for (ll i = 2; i*i<= t; i++) {
    if (t%i == 0)return false;}return true;
}ll mod_pow(ll x, ll n, ll mod) {
    ll res = 1;while (n > 0) {
    if (n & 1) res = res*x%mod;x = x*x%mod;n >>= 1;}return res;
}int main() {
    ll p, a;while (scanf("%lld%lld",&p,&a)!=EOF) {
    if (p == 0 && a == 0)break;if (Prime(p)) {
    cout << "no" << endl;continue;}ll res = mod_pow(a, p, p);if (res == a)cout << "yes" << endl;else cout << "no" << endl;}
}