Pseudoprime numbers---费马小定理
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 13406 | Accepted: 5792 |
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的值判断,若p为素数,就断定不是伪素数,若p不是素数,则判断式子(a^n)%p==a;若相等,
则输出yes,否则输出no;由于数据较大,故容易超时,费马小定理;*/
难受的是sqrt函数返回的是double型,在类型转换的时候poj一直提示compile error,浪费了我好多时间
这里再说一下sqrt()函数:
sqrt()函数,里面的形参是double型的,所以调用的时候,要强制转换成double型。
sqrt()函数都最后返回值是double型,而n是int型,所以要强制转换n=(int)sqrt((double)x);
#include<iostream> #include<string.h> #include<math.h> #define max 0x3f3f3f3f #define ll long long #define mod 1000000007 using namespace std; ll vis[100005]; ll cnt = 0; int isprime(ll p) { int x=(double)sqrt(p)+0.5; for(ll i=2;i<=x;i++) if(p%i==0) return 0; return 1; } ll f(ll a, ll b, ll n) //定义函数,求a的b次方对n取模 { ll t, y; t = 1; y = a; while (b != 0) { if ((b & 1) == 1) t = t * y%n; y = y * y%n; b = b >> 1; } return t; } int main() { ll a, p; while (cin >> p >> a) { if (a == 0 && p == 0) break; else { if (isprime(p)) cout << "no" << endl; else if (a == f(a, p, p)) cout << "yes" << endl; else cout << "no" << endl; } } return 0; }