您的位置:首页 > 运维架构

【 POJ 3641 】Pseudoprime numbers

2016-07-23 18:54 405 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: