POJ 1811 Prime Test(大素数判断和素因子分解)

来源:互联网 发布:小说写作软件 编辑:程序博客网 时间:2024/05/22 08:22

problem

Given a big integer number, you are required to find out whether it’s a prime number.

Input

The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 2 54).

Output

For each test case, if N is a prime number, output a line containing the word “Prime”, otherwise, output a line containing the smallest prime factor of N.

Sample Input

2
5
10

Sample Output

Prime
2


代码实例

//miller_rabin 算法进行素数测试#include<iostream>#include<stdlib.h>#include<time.h>#include<cstdio>using namespace std;const int S=10;//随机算法进行素数测试,一般大于10就ok//快速乘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 temp=a%mod;    while(n)    {        if(n&1) ret=mult_mod(ret,temp,mod);        temp=mult_mod(temp,temp,mod);        n>>=1;    }    return ret;}//通过a^(n-1)=1(mod n)来判断n是不是素数//n-1  =x *2^t 中间使用二次判断//是合数返回true 不一定是合数返回falsebool 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;}//miller_rabin算法//是素数返回true,(可能是伪素数)//不是素数返回falsebool 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++;    }    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[1000];//质因数分解结果(刚返回时是无序的)int tol;//质因数的个数,编号0~tol-1//gcdlong 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;    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;        }    }}//对n进行素因子分解,存入factor,k设置为107左右即可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(){    ios::sync_with_stdio(false);    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("%lld\n",ans);        }    }    return 0;}
阅读全文
0 0
原创粉丝点击