大素数判断+求最小质因数(模板)——pku3641

/*******************************************************************************************这里包含了rabinmiller素数测试与pollard算法求解最小质因数的方法,函数说明放到每个函数的前面*******************************************************************************************/
不是自己写的学习一下
大素数判断+求最小质因数(模板)——pku3641 View Code
   
     
/* ******************************************************************************************
这里包含了rabinmiller素数测试与pollard算法求解最小质因数的方法,函数说明放到每个函数的前面
******************************************************************************************
*/

#include
< stdio.h >
#include
< stdlib.h >
typedef unsigned __int64 hugeint;
// 求出最大公约数
hugeint gcd(hugeint A, hugeint B)
{
while (A != 0 )
{
hugeint C
= B % A;
B
= A;
A
= C;
}
return B;
}

// 求a*b%c,要求:a,b的范围在hugeint范围的一般以内,在hugeint为unsigned __int64时,a,b需要是__int64能表示的数
hugeint product_mod(hugeint A, hugeint B, hugeint C)
{
hugeint R, D;
R
= 0 ;
D
= A;
while (B > 0 )
{
if ( B & 1 ) R = (R + D) % C;
D
= (D + D) % C;
B
>>= 1 ;
}
return R;
}

// 求a^b%c,要求:a,b的范围在hugeint范围的一般以内,在hugeint为unsigned __int64时,a,b需要是__int64能表示的数
hugeint power_mod(hugeint A, hugeint B, hugeint C)
{
hugeint R
= 1 , D = A;
while (B )
{
if (B & 1 ) R = product_mod(R, D, C);
D
= product_mod(D, D, C);
B
>>= 1 ;
}
return R;
}

// 给出随机数,可以简单的用rand()代替
hugeint rAndom()
{
hugeint a;
a
= rand();
a
*= rand();
a
*= rand();
a
*= rand();
return a;
}

// rabinmiller方法测试n是否为质数
int pri[] = { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 };
bool isprime(hugeint n)
{
if (n < 2 )
return false ;
if (n == 2 )
return true ;
if ( ! (n & 1 ))
return false ;
hugeint k
= 0 , i, j, m, a;
m
= n - 1 ;
while (m % 2 == 0 )
m
= (m >> 1 ), k ++ ;
for (i = 0 ; i < 10 ; i ++ )
{
if (pri[i] >= n) return 1 ;
a
= power_mod( pri[i], m, n );
if (a == 1 )
continue ;
for (j = 0 ; j < k; j ++ )
{
if (a == n - 1 ) break ;
a
= product_mod(a,a,n);
}
if (j < k)
continue ;
return false ;
}
return true ;
}

// pollard_rho分解,给出N的一个非1因数,返回N时为一次没有找到
hugeint pollard_rho(hugeint C, hugeint N)
{
hugeint I, X, Y, K, D;
I
= 1 ;
X
= rand() % N;
Y
= X;
K
= 2 ;
do
{
I
++ ;
D
= gcd(N + Y - X, N);
if (D > 1 && D < N) return D;
if (I == K) Y = X, K *= 2 ;
X
= (product_mod(X, X, N) + N - C) % N;
}
while (Y != X);
return N;
}

// 找出N的最小质因数
hugeint rho(hugeint N)
{
if (isprime(N)) return N;
do
{
hugeint T
= pollard_rho(rand() % (N - 1 ) + 1 , N);
if (T < N)
{
hugeint A, B;
A
= rho(T);
B
= rho(N / T);
return A < B ? A : B;
}
}
while ( true );
}

int main ()
{

int t;
hugeint n, ans;

scanf (
" %d " , & t );
while ( t -- )
{
scanf (
" %I64d " , & n );

ans
= rho ( n );
if ( ans == n )
{
printf (
" Prime\n " );
}
else
{
printf (
" %I64d\n " , ans );
}
}
return 0 ;
}

你可能感兴趣的:(pku)