POJ 1811 Prime Test --- Miller 素数测试

来源:互联网 发布:如何开手机淘宝 编辑:程序博客网 时间:2024/06/11 23:32

SOL:学下那个算法就OK了。。。

此题向我这么写只能用C++交,要不就RE,POJ 不让那么写随机数。


#include <stdio.h>#include <math.h>#include <cstring>#include <algorithm>#include <stdlib.h>#include <time.h>using namespace std;const int S = 8;//随即算法判定 long long mult_mod(long long a,long long b,long long c){a%=c;b%=c;long long ret=0;long long tmp=a;while(b){if(b&1){ret+=tmp;if(ret>c) ret-=c;}tmp<<=1;if(tmp>c) tmp-=c;b>>=1;}return ret;}long long pow_mod(long long a,long long n,long long mod){long long ret=1;long long tmp=a%mod;while(n){if(n&1) ret=mult_mod(ret,tmp,mod);tmp=mult_mod(tmp,tmp,mod);n>>=1;}return ret;}bool check(long long a,long long n,long long x,long long t){long long ret=pow_mod(a,x,n);long long 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;}bool Miller_Rabin(long long n){if(n<2) return false;if(n==2) return true;if((n&1)==0) return false;long long x=n-1;long long t=0;while((x&1)==0){x>>=1;t++;}srand(time(NULL));for(int i=0;i<S;i++){long long a=rand()%(n-1)+1;if(check(a,n,x,t)) return false;}return true;}long long factor[100];int tol;long long gcd(long long a,long long b){long long t;while(b){t=a;a=b;b=t%b;}if(a>=0) return a;else return -a;}long long pollard_rho(long long x,long long c){long long i=1,k=2;srand(time(NULL));long long x0=rand()%(x-1)+1;long long y=x0;while(1){i++;x0=(mult_mod(x0,x0,x)+c)%x;long long d=gcd(y-x0,x);if(d!=1&&d!=x) return d;if(y==x0) return x;if(i==k){y=x0;k+=k;}}}void findfac(long long n,int k){if(n==1) return;if(Miller_Rabin(n)){factor[tol++]=n;return;}long long p=n;int c=k;while(p>=n)p=pollard_rho(p,c--);findfac(p,k);findfac(n/p,k);}int main(){int T;long long n;scanf("%d",&T);while(T--){scanf("%I64d",&n);if(Miller_Rabin(n))printf("Prime\n");else{tol=0;findfac(n,107);long long ans=factor[0];for(int i=1;i<tol;i++)ans=min(ans,factor[i]);printf("%I64d\n",ans);}}return 0;}


0 0
原创粉丝点击