Pollard-Rho算法(模板)

对于每个数字检验是否是质数,是质数就输出Prime;如果不是质数,输出它最大的质因子是哪个。

#include<bits/stdc++.h>
using namespace std;
 
long long fast_mul(long long x,long long y,long long p)//return x*y mod p
{
    return (__int128)x*y%p;
}
long long fast_pow(long long x,long long y,long long p)//return x^y mod p
{
    long long ans=1;
    while(y)
    {
        if(y&1)
            ans=fast_mul(ans,x,p);
        x=fast_mul(x,x,p);
        y>>=1;
    }
    return ans;
}
bool is_prime(long long n)
{
    if(n<=1)
        return 0;
    static const int pr[]={2,3,5,7,11,13,17,19,23,29,31,37};
    for(auto a:pr)
    if(n%a==0)
        return n==a;
    long long n1=n-1;int l=0;
    while(n1%2==0){n1/=2;++l;}
    for(auto a:pr)
    {
        long long x=fast_pow(a,n1,n);
        if(x==1||x==n-1)continue;
        int j=0;
        while(++j<l)
        {
            x=fast_mul(x,x,n);
            if(x==n-1)break;
        }
        if(j>=l)return 0;
    }
    return 1;
}
int ra_32()
{
    return RAND_MAX<=32768?rand()*32768+rand():rand();
}
long long ra_64()
{
    return ((long long)ra_32()<<32)+ra_32();
}
long long find(long long n)
{
    if(n%2==0)return 2;//因子2要特判
    long long x=ra_64()%n,y=x,c=ra_64()%n;
    auto F=[&](long long x)->long long
    {
        return (fast_mul(x,x,n)+c)%n;
    };
    static const int step=100;
    while(1)
    {
        long long x0=x,y0=y,product=1;
        for(int i=1;i<=step;++i)
        {
            x=F(x);y=F(F(y));   
            product=fast_mul(product,abs(x-y),n);
        }
        if(__gcd(product,n)>1)
        {
            x=x0;y=y0;
            while(1)
            {
                x=F(x);y=F(F(y));
                long long d=__gcd(abs(x-y),n);
                if(d>1)return d;
            }
        }
    }
}
vector<long long>prime_factor;
void fen(long long n)
{
    if(is_prime(n)){prime_factor.push_back(n);return ;}
    long long i;
    while((i=find(n))==n);
    fen(i);fen(n/i);
}
 
int main()
{
    int case_num;
    cin>>case_num;
    for(int i=1;i<=case_num;++i)
    {
        long long x;
        scanf("%lld",&x);
        prime_factor.clear();
        fen(x);   
        sort(prime_factor.begin(),prime_factor.end());
        if(prime_factor.size()==1)puts("Prime");
        else printf("%lld\n",prime_factor.back());
    }
}
发布了195 篇原创文章 · 获赞 27 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lgz0921/article/details/98475042