zoj 月赛B题(快速判断一个大数是否为素数)
给出一个64位的大数,如何快速判断其是否为素数
#include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; typedef long long LL; LL n,m; //**************************************************************** // Miller_Rabin 算法进行素数测试 //速度快,而且可以判断 <2^63的数 //**************************************************************** const int S=20;//随机算法判定次数,S越大,判错概率越小 LL mult_mod(LL a,LL b,LL mod) //(a*b)%c a,b,c<2^63 { a%=mod; b%=mod; LL ans=0; while(b) { if(b&1) { ans=ans+a; if(ans>=mod) ans=ans-mod; } a=a<<1; if(a>=mod) a=a-mod; b=b>>1; } return ans; } LL pow_mod(LL a,LL b,LL mod) // a^b%mod { LL ans=1; a=a%mod; while(b) { if(b&1) { ans=mult_mod(ans,a,mod); } a=mult_mod(a,a,mod); b=b>>1; } return ans; } //以a为基,n-1=x*2^t a^(n-1)=1(mod n) 验证n是不是合数 //一定是合数返回true,不一定返回false bool check(LL a,LL n,LL x,LL t) { LL ret=pow_mod(a,x,n); LL last=ret; for(int i=1;i<=t;i++) { ret=mult_mod(ret,ret,n); if(ret==1 && last!=1 && last!=n-1) return true;//合数 last=ret; } if(ret!=1) return true; else return false; } // Miller_Rabin()算法素数判定 //是素数返回true.(可能是伪素数,但概率极小) //合数返回false; bool Miller_Rabin(long long n) { if(n<2)return false; if(n==2) return true; if( (n&1)==0) return false;//偶数 LL x=n-1; LL t=0; while( (x&1)==0 ) { x>>=1;t++;} for(int i=0;i<S;i++) { LL a=rand()%(n-1)+1;//rand()需要stdlib.h头文件 if(check(a,n,x,t)) return false;//合数 } return true; } int main() { // n,m; while(scanf("%lld%lld",&n,&m)>0) { LL sum=0; for(LL i=0; i<m; i++) { sum+=(LL)(pow((double)(n),i)+0.5); } //printf("%lld\n",sum); if(Miller_Rabin(sum)) printf("YES\n"); else printf("NO\n"); } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。