Pollard-Rho算法(模板)

本文介绍了一种高效的算法,用于检测一个数字是否为质数,并在非质数情况下找到其最大质因子。通过快速乘法、幂运算、随机数生成等技术,实现了对大整数的有效处理。

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

对于每个数字检验是否是质数,是质数就输出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());
    }
}

 

Pollard's rho algorithm是一种用于寻找大整数乘法下的隐含因子或离散对数的素数分解算法。在NTL库(Number Theoretic Library),这是一个广泛使用的C++库,它提供了高效的数学工具,包括处理大整数。 在NTL中实现Pollard rho算法求解离散对数可能会涉及以下几个步骤: 1. 定义函数生成器:通常选择两个互逆的函数f(x)和g(x),如f(x) = (x^2 + 1) % p 或者是一个随机多项式。 2. 初始化:选择两个初始值x0和y0,并计算它们的迭代值xi = f(xi) 和 yi = f(g(yi))。 3. 遍历过程:重复应用函数直到找到两个序列长度相近的质因数分解点,即存在整数t使得yi ≡ xi + t * gy模p。 4. 寻找线性关系:检查yi - xi 是否可以表示为两个连续项的差,即是否存在k使得yi - xi = k * (gi - gi-1) mod p。如果找到这样的线性关系,那么gcd(xi - gy, p) 可能就是离散对数的结果。 5. 如果找到了一个非平凡因子,则继续搜索直到找到p-1或者找到离散对数;否则,尝试调整初始值或函数生成器并继续。 在实际操作中,NTL会提供优化过的数据结构和函数来提高性能。以下是一个简化版的伪代码示例(注意,这只是一个概述,NTL的具体API和实现细节需要查看官方文档或源码): ```cpp #include <NTL/ZZX.h> // ... ZZX f(ZZX x); ZZX g(ZZX y, ZZ p); ZZX x0, y0; ZZ n; while (true) { x0 = f(x0); y0 = f(g(y0, p)); ZZX xi = x0, yi = y0; for (ZZ i = 1; i < n; ++i) { xi = f(xi); yi = f(g(yi, p)); if (yi - xi == k * (gi - g(i-1))) { // 找到线性关系,尝试解开离散对数 break; } } // ...处理其他情况和循环 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心脏dance

如果解决了您的疑惑,谢谢打赏呦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值