poj1811(大质数判定与大数分解的模板题)

来源:互联网 发布:域名对应多个ip 编辑:程序博客网 时间:2024/04/29 13:00

题目大意:输入一个数(<2^54),判断其是否为质数,如果否,输出其最小质因数。

经过两篇博客详解,相信这道题目完成应该没有问题了。下面附上代码。

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;LL ans;LL modmul(LL a,LL b,LL mod){LL ret=0;for(;b;b>>=1,a=(a+a)%mod)if(b&1)ret=(ret+a)%mod;return ret;}LL qpow(LL x,LL u,LL mod){LL ret=1LL;for(;u;u>>=1,x=modmul(x,x,mod))if(u&1)ret=modmul(ret,x,mod);return ret;}LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}LL Pollard_Rho(LL n,LL c){LL i=1,j=2,x=rand()%(n-1)+1,y=x;while(1){i++;x=(modmul(x,x,n)+c)%n;LL p=gcd((y-x+n)%n,n);if(p!=1&&p!=n)return p;if(y==x)return n;if(i==j){y=x;j<<=1;}}}bool Miller_Rabin(LL n){LL x,pre,u=n-1;int i,j,k=0;if(n==2||n==3||n==5||n==7||n==11)return 1;if(n==1||!(n%2)||!(n%3)||!(n%5)||!(n%7)||!(n%11))return 0;while(!(u&1)){k++;u>>=1;}srand((long long)12234336);for(i=1;i<=50;i++){x=rand()%(n-2)+2;if(!(n%x))return 0;x=qpow(x,u,n);pre=x;for(j=1;j<=k;j++){x=modmul(x,x,n);if(x==1&&pre!=1&&pre!=n-1)return 0;pre=x;}if(x!=1)return 0;}return 1;}void find(LL n,LL c){if(n==1)return;if(Miller_Rabin(n)){ans=min(ans,n);return;}LL x=n,k=c;while(x==n)x=Pollard_Rho(x,c--);find(n/x,k);find(x,k);}int main(){int _;LL n;scanf("%d",&_);while(_--){scanf("%lld",&n);if(Miller_Rabin(n))puts("Prime");else{ans=1LL<<62;find(n,120);printf("%lld\n",ans);}}return 0;}


0 0
原创粉丝点击