POJ 1811 Prime Test(素数测试和分解)

题目链接:http://poj.org/problem?id=1811

题意:给定一个数判断是不是素数;不是输出最小的素因子。

思路:millerRabin判断是不是素数;pollard分解。









i64 Gcd(i64 x,i64 y)

{

    return !y?x:Gcd(y,x%y);

}



i64 binMultip(i64 a,i64 b,i64 mod)

{

    i64 ans=0;

    while(b)

    {

        if(b&1) (ans+=a)%=mod;

        (a+=a)%=mod;

        b>>=1;

    }

    return ans;

}



i64 binPower(i64 a,i64 b,i64 mod)

{

    i64 ans=1;

    while(b)

    {

        if(b&1) ans=binMultip(ans,a,mod);

        a=binMultip(a,a,mod);

        b>>=1;

    }

    return ans;

}



int witness(i64 a,i64 n)

{

    i64 m=n-1,x,y,k=0;

    while(m%2==0) k++,m>>=1;

    x=binPower(a,m,n);

    while(k--)

    {

        y=binMultip(x,x,n);

        if(y==1&&x!=1&&x!=n-1) return 1;

        x=y;

    }

    return y!=1;

}



int millerRabin(int cnt,i64 n)

{

    if(n==2) return 1;

    if(n==1||n%2==0) return 0;

    i64 a;

    while(cnt--)

    {

        a=rand()%(n-1)+1;

        if(witness(a,n)) return 0;

    }

    return 1;

}



i64 pollard(i64 n,int c)

{

    i64 x,y,d,k=2,i=1;

    x=y=rand()%n;

    while(1)

    {

        x=(binMultip(x,x,n)+c)%n;

        d=Gcd(y-x,n);

        if(d>1&&d<n) return d;

        if(y==x) return n;

        if(++i==k) y=x,k<<=1;

    }

}



i64 minPrime;



void getMinPrime(i64 n,int c)

{

    if(n==1) return;

    if(millerRabin(12,n))

    {

        minPrime=min(minPrime,n);

        return;

    }

    i64 m=n;

    while(m==n) m=pollard(m,c--);

    getMinPrime(m,c);

    getMinPrime(n/m,c);

}



int C;

i64 n;



int main()

{

    RD(C);

    while(C--)

    {

        RD(n);

        if(millerRabin(12,n)) puts("Prime");

        else

        {

            minPrime=n;

            getMinPrime(n,100);

            PR(minPrime);

        }

    }

    return 0;

}

  

你可能感兴趣的:(test)