Pseudoprime numbers
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8702 Accepted: 3658
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
—————————————————————————————————————————————
题意:给伪素数一个定义,根据费马小定理ap = a (mod p)的非素数被称为伪素数,输入若干组a、p判断是不是伪素数,是输出yes,不是输出no。
一开始一直没看懂“ ap = a (mod p) ”这是什么玩意,后来用计算器凑了凑数据,估摸着是 (a^p)%p == a (因为p>a) ,后来试了一下,果然就是这样。
一个素数判断加一个快速幂,速度出代码。(一开始用了素数打表,后来激动地函数写完了回头看了一眼范围……默默的删掉重写)
最坑的是调用的时候一不小心把函数名掉了,结果找了半天。
上代码:
——————————————————————————————————————————————
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#define M 1000000000+10 //如果数量太多不适宜用素数打表,容易栈溢出
using namespace std;
int isprime(long long n) //用了类似于素数打表的技巧,优化一下
{
if(n == 2)
return 1;
if(n <= 1 || n%2 == 0)
return 0;
long long j = 3;
while( j <= (long long)sqrt(double(n)) )
{
if( n%j == 0 )
return 0;
j += 2;
}
return 1;
}
long long pow( long long a1, long long b,long long mod)
{ //一般快速幂
long long r = 1,base = a1;
while( b )
{
if( b&1 ) //位运算 b%2 == 1
{
r = ( base*r )%mod; //取b为奇数的时候相乘
}
base = (base*base)%mod;
b>>=1; // b/=2;
}
return r;
}
//简介快速幂:
// (偶数) a^n=((a^2)^n/2)=((a^2)^2)^n/4)=(((a^2)^2)^2)^n/8)=.....
//(奇数)a^n=(((a^2)^n/2)*a)=......(把多余的a拿出来乘给r,相当于先储存进r中,其他的和偶数一样)
//最后b一定会有一次等于一,把储存进r的和没有存进r的相乘最后输出结果。
int main()
{
long long ad,p,MOD;
while( ~scanf("%lld%lld",&p,&ad) && !( ad==0 && p==0 ) )
{
if( isprime(p) )
{
printf("no\n");
continue;
}
MOD=pow(ad,p,p); //函数名不加,活该 WA 一辈子⊙﹏⊙
if( ad == MOD )printf("yes\n");
else printf("no\n");
}
return 0;
}