【 POJ 3641 】Pseudoprime numbers
2016-07-23 18:54
405 查看
Pseudoprime numbers
Time Limit: 1000MS Memory Limit: 65536KTotal 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; }
相关文章推荐
- mongoperf用法
- linux服务之irqbalance
- linux 操作系统中显示数据包到主机的路径traceroute命令的使用
- ubuntu安装(owncloud-docker安装)
- linux 操作系统中检查特定用户上次登录的时间lastlog命令的使用
- OpenLayers3入门篇-点在线上的运动
- Linux下的软件源代码安装
- linux 操作系统中列出目前与过去登录系统的用户信息last命令的使用
- OPENGL的入门第一个程序——Hello World
- linux 操作系统中查看发送电子邮件mail命令的使用
- 《架构探险》之依赖注入
- linux 操作系统中ifconfig查看和设置网卡信息命令的使用
- linux 进程间消息队列通讯
- VC6.0 配置OpenCV1.0
- linux 操作系统中wall命令的使用
- linux 操作系统中write命令的使用
- Linux上的安装与配置Tomcat
- 退出python shell
- OPRNGL总结(一)OPENGL的理论原理
- linux中–lm 有什么用