POJ 1811 Prime Test

本文介绍了如何通过`pollard_rho`和`miller_rabin`算法快速判断一个整数是否为质数,并提供了一个实现案例,包括快速幂运算注意事项、算法实现细节及代码优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接 : POJ1811

Prime Test
Time Limit: 6000MS Memory Limit: 65536K
Total Submissions: 26044 Accepted: 6333
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 < 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

Source

 

pollard_rho 和 miller_rabin 算法

快速幂的时候注意会超longlong

还有其他素数测试算法 戳这里

 

自己的代码  500ms

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
using namespace std;

int kk=1<<31;
long long pow_mult(long long a,long long b,long long mod)
{
    a%=mod;b%=mod;
    if(a<kk && b<kk) return a*b%mod;
    long long c=0;
    while(b)
    {
        if(b&1)
        {
            c=c+a;
            if(c>=mod) c-=mod;
        }
        b>>=1;
        a<<=1;
        if(a>=mod) a-=mod;
    }
    return c;
}
long long pow_mod(long long a,long long b,long long mod)
{
    a%=mod;
    long long c=1;
    while(b)
    {
        if(b&1) c=pow_mult(c,a,mod);
        b>>=1;
        a=pow_mult(a,a,mod);
    }
    return c;
}
long long gcd(long long a,long long b)
{
    long long c=a%b;
    while(c)
    {
        a=b;b=c;
        c=a%b;
    }
    return b;
}
long long pollard_rho(long long n)
{
    if(n==2) return 0;
    if((n&1)==0) return 2;
    long long d,x1,x2;
    for(int i=1;i<100;i++)
    {
        x1=rand()%n;
        x2=(pow_mult(x1,x1,n)+n-1)%n;
        d=gcd((x2+n-x1)%n,n);
        while(d==1)
        {
            x1=(pow_mult(x1,x1,n)+n-1)%n;
            x2=(pow_mult(x2,x2,n)+n-1)%n;
            x2=(pow_mult(x2,x2,n)+n-1)%n;
            d=gcd((x2+n-x1)%n,n)%n;
        }
        if(d) return d;
    }
    return 0;
}
bool miller_rabin(long long n)
{
    if(n==1) return 1;
    long long u,x1,x2;
    int t;
    for(int i=0;i<3;i++)
    {
        long long a=rand()%(n-1)+1;
        u=n-1;t=0;
        while(u%2==0) u>>=1,t++;
        x1=pow_mod(a,u,n);
        for(int i=0;i<t;i++)
        {
            x2=pow_mult(x1,x1,n);
            if(x2==1 && x1!=1 && x1!=n-1) return 0;
            x1=x2;
        }
        if(x1!=1) return 0;
    }
    return 1;
}
long long prim(long long n)
{
    if(miller_rabin(n)) return n;
    return prim(pollard_rho(n));
}
int main()
{
 //   freopen("1.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long n,fin,temp,m;
        scanf("%lld",&n);
        m=fin=n;
        for(int i=0;i<10 && n!=1;i++)
        {
            temp=prim(n);
            n/=temp;
            if(fin>temp) fin=temp;
        }
        if(fin!=m) printf("%lld\n",fin);
        else printf("Prime\n");
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值