HDU1905 Pseudoprime numbers

本文介绍了一种基于费马小定理的伪素数判断算法,并通过C++实现了一个简单的程序来验证特定条件下整数是否为基apseudoprime伪素数。该算法适用于2到1,000,000,000范围内的整数。

Pseudoprime numbers

Time Limit: 1000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 633Accepted Submission(s): 258

Problem Description
Fermat's theorem states that for any prime number p and for any integer a > 1, a^p == 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 ≤ 1,000,000,000 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
【解题思路】这是一道不错的数论题目,可以学到很多东西,比如说将指数很大的数进
行二进制处理,还有就是判断素数和伪素数。最有用的知识点是:
1、如果p是奇数,则有(a.^p)mod(m)==((a%m)*(a.^(p-1)%m)%m成立;
2、如果p是偶数,则有a.^p==a.^(p/2)*a.^(p/2)。

也许可以说这两个结论人人都知道,但用起来就不是那么一回事了。

#include<iostream> using namespace std; int plist[100001],pcount=0; int prime(int n){ int i; if ((n!=2&&!(n%2))||(n!=3&&!(n%3))||(n!=5&&!(n%5))||(n!=7&&!(n%7))) return 0; for (i=0;plist[i]*plist[i]<=n;i++) if (!(n%plist[i])) return 0; return n>1; } void initprime(){ int i; for (plist[pcount++]=2,i=3;i<100000;i++) if (prime(i)) plist[pcount++]=i; } __int64 _mode(__int64 a,__int64 m) { __int64 ans=1,exp=m; while(exp) { if(exp%2==1) ans=(ans*a)%m; a=(a*a)%m; exp=exp/2; } return ans; } int main() { __int64 pp,a; int i,j; initprime(); scanf("%I64d %I64d",&pp,&a); while(1) { if(pp==0 &&a==0) break; if(prime(pp)==1) { cout<<"no"<<endl; } else { if(_mode(a,pp)==a) cout<<"yes"<<endl; else cout<<"no"<<endl; } scanf("%I64d %I64d",&pp,&a); } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值