Pollard-Rho

\(code:\)

ll pri[12]={2,3,5,7,11,13,17,19};
ll mul(ll x,ll y,ll mod)
{
    ll c=(long double)x*y/mod+0.5;
    c=x*y-c*mod;
    return c<0?c+mod:c;
}
ll qp(ll x,ll y,ll mod)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=mul(ans,x,mod);
        x=mul(x,x,mod);
        y>>=1;
    }
    return ans%mod;
}
bool check(ll x,ll p,ll mod)
{
    ll t=qp(x,p,mod);
    if(t==mod-1) return true;
    if(t==1) return p&1?true:check(x,p/2,mod);
    return false;
}
bool Miller_Rabin(ll n)
{
    if(n==1) return false;
    if(n<=3) return true;
    if(!(n&1)) false;
    for(int i=0;i<8;++i)
    {
        if(n==pri[i]) return true;
        if(!check(pri[i],n-1,n)) return false;
    }
    return true;
}
ll gcd(ll a,ll b)
{
    return b?gcd(b,a%b):a;
}
ll f(ll x,ll y,ll mod)
{
    return (mul(x,x,mod)+y)%mod;
}
ll Pollard_Rho(ll x)
{
    ll s=0,t=0,c=(ll)1*rand()%(x-1)+1,val=1;
    for(ll goal=1;;goal<<=1,s=t,val=1)
    {
        for(ll step=1;step<=goal;++step)
        {
            t=f(t,c,x);
            val=mul(val,abs(t-s),x);
            if(step%127==0)
            {
                ll d=gcd(val,x);
                if(d>1) return d;
            }
        }
        ll d=gcd(val,x);
        if(d>1) return d;
    }
}
void fac(ll x)
{
    if(x<=fac_max||x<2) return;
    if(Miller_Rabin(x)) 
    {
        fac_max=max(fac_max,x);
        return;
    }
    ll p=x;
    while(p>=x) p=Pollard_Rho(x);
    while(x%p==0) x/=p;
    fac(x),fac(p);
}

猜你喜欢

转载自www.cnblogs.com/lhm-/p/12229775.html