求最小素因子(pollard-rho)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define LL long long
using namespace std;
 
inline LL mul(LL a,LL b,LL P)
{
    a=(a%P+P)%P,b=(b%P+P)%P;
    return (a*b - (LL)((long double)a/P*b+1e-10)*P+P)%P;
}
 
inline LL Pow(LL base,LL k,LL P)
{
    LL ret=1;
    for(base%=P;k;k>>=1,base=mul(base,base,P))
        if(k&1)
            ret=mul(ret,base,P);
    return ret;
}
 
bool Miller_Rabbin(LL x)
{
    if(x==2) return 1;
    LL t=0,res=x-1;
    for(;!(res & 1);t++,res>>=1); 
    for(int i=1;i<10;i++)
    {
        LL a=rand()%(x-2)+2,now=Pow(a,res,x),pre=now;
        for(int j=0;j<t;j++,pre=now)
            if((now=mul(pre,pre,x))==1 && pre!=1 && pre!=x-1) return 0;
        if(now!=1) return 0;
    }
    return 1;
}
 
LL gcd(LL a,LL b){ return !b?a:gcd(b,a%b); }
 
LL Rho(LL x,LL c)
{
    LL a=rand()%(x-1)+1,b=a,tmp,k=1,i=1,d=1;
    for(;d==1;k++)
    {
        d=gcd(abs((a=((mul(a,a,x)+c)%x))-b) , x);
        (k==i) && (b=a , i<<=1);
    }
    if(d==x) d=Rho(x,c+1);
    return d;
}
 
LL seq[10000];
void Pollard(LL x)
{
    if(Miller_Rabbin(x))
    {
        seq[++seq[0]]=x;
        return ;
    }
    LL tmp=x;
    tmp=Rho(tmp,3);
    Pollard(tmp),Pollard(x/tmp);
}
 
int main()
{
    int T;scanf("%d",&T);
    srand(998244353);
    for(;T--;seq[0]=0)
    {
        LL n;
        scanf("%lld",&n);
        Pollard(n);
        if(seq[0]==1) printf("Prime\n");
        else printf("%lld\n",*min_element(seq+1,seq+1+seq[0]));
    }
}
/**************************************************************
    Problem: 2140
    User: C20182422
    Language: C++
    Result: 正确
    Time:24 ms
    Memory:1116 kb
****************************************************************/

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/78328945