poj 1811 Prime Test 大数素数测试模板

Prime Test

Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 37752   Accepted: 10155
Case Time Limit: 4000MS

Description

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 < 254).

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

模板代码:

/*来自:李双智学长模板*/
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<stdlib.h>
#include<time.h>
#define times 20
using namespace std;
long long total;
long long factor[110];
long long qmul(long long a,long long b,long long M){
    a%=M;
    b%=M;
    long long ans=0;
    while (b){
        if (b&1){
            ans=(ans+a)%M;
        }
        a=(a<<=1)%M;
        b>>=1;
    }
    return ans%M;
}//快乘,因为两个longlong的数相乘可能会溢出,所以这里转乘法为加法,思想和快速幂相似
long long qpow(long long a,long long b,long long int M){
    long long ans=1;
    long long k=a;
    while(b){
        if(b&1)ans=qmul(ans,k,M)%M;
        k=qmul(k,k,M)%M;
        b>>=1;
    }
    return ans%M;
}//快速幂
bool witness(long long a,long long n,long long x,long long sum){
    long long judge=qpow(a,x,n);
    if (judge==n-1||judge==1)return 1;
    while (sum--){
        judge=qmul(judge,judge,n);
        if (judge==n-1)return 1;
    }
    return 0;
}
bool miller(long long n){
    if (n<2)return 0;
    if (n==2)return 1;
    if ((n&1)==0)return 0;
    long long x=n-1;
    long long sum=0;
    while (x%2==0){
        x>>=1;
        sum++;
    }
    for (long long i=1;i<=times;i++){
        long long a=rand()%(n-1)+1;
        if (!witness(a,n,x,sum))return 0;//费马小定理的随机数检验
    }
    return 1;
}//判断一个数是否为素数
long long gcd(long long a,long long b){
    return b==0?a:gcd(b,a%b);
}//欧几里得算法
long long pollard(long long n,long long c){
    long long x,y,d,i=1,k=2;
    x=rand()%n;
    y=x;
    while (1){
        i++;
        x=(qmul(x,x,n)+c)%n;
        d=gcd(y-x,n);
        if (d<0)d=-d;
        if (d>1&&d<n)return d;
        if (y==x)return n;
        if (i==k){
            y=x;
            k<<=1;
        }
    }
}
void find(long long n){
    if (miller(n)){
        factor[++total]=n;
        return ;
    }
    long long p=n;
    while (p>=n){
        p=pollard(p,rand()%(n-1)+1);
    }
    find(n/p);
    find(p);
}//寻找这个数的素因子,并存起来
int main(){
    long long n,m,i,t;
    scanf("%lld",&t);
    while (t--){
        scanf("%lld",&n);
        if (miller(n)){
            printf("Prime\n");
        }
        else {
            memset(factor,0,sizeof(factor));
            total=0;
            find(n);
            sort(factor+1,factor+total+1);
            printf("%lld\n",factor[1]);//输出最小的素数因子
        }
    }
}

猜你喜欢

转载自blog.csdn.net/SunPeishuai/article/details/81511658