本文主要是介绍POJ 3641 Pseudoprime numbers 快速幂+判断素数 快速幂模板,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接
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;}
}
这篇关于POJ 3641 Pseudoprime numbers 快速幂+判断素数 快速幂模板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!