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

/*******************************************************************************************这里包含了rabinmiller素数测试与pollard算法求解最小质因数的方法,函数说明放到每个函数的前面*******************************************************************************************/
不是自己写的学习一下
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;
}
原文地址:https://www.cnblogs.com/huhuuu/p/2032191.html