【POJ】-3641-Pseudoprime numbers(快速幂,大数素数判定)

来源:互联网 发布:java reentrantlock 编辑:程序博客网 时间:2024/05/16 17:31

Pseudoprime numbers
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 8607 Accepted: 3616

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-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 210 3341 2341 31105 21105 30 0

Sample Output

nonoyesnoyesyes

题意:费马定理:任意素数p和任意整数a(a>1)有如下性质:a的p次方除以p的余数等于a。
有一些同样具有这个性质的非素数p被称为基数a的伪素数。
现在给定两个数p和a,问p是否是a的伪素数。是的话输出“yes”,反之输出“no”

就是说p如果不是素数判断:(a^p)%p==a,如果成立就是yes。

题解:1,首先判断p是不是素数。p范围很大,不可以打表。

2,p是素数输出no;不是进行判断。


#include<cstdio>#include<cmath>__int64 dis(__int64 n,__int64 m)__int64 ans=1;__int64 t=m;//临时变量t存放m,因为下面m会变 while(m){if(m&1)ans=(ans*n)%t;n=(n*n)%t;m>>=1;}return ans;} int main(){__int64 p,a;while(~scanf("%I64d %I64d",&p,&a)&&p&&a){int k=sqrt(p);for(int i=2;i<=k;i++)//判断p是不是素数,从2到更号p {if(p%i==0){k=0;//可以整出一个i,不是素数,标记k=0,退出 break;}}if(!k)//p不是素数,进行运算 {__int64 z=dis(a,p);if(z==a)printf("yes\n");elseprintf("no\n");}elseprintf("no\n");}return 0;}

0 0
原创粉丝点击