Prime Test
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 16552 | Accepted: 3310 | |
Case Time Limit: 4000MS |
Description
Given a big integer number, you are required to find out whether it's a prime number.
Input
The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 2
54).
Output
For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.
Sample Input
2 5 10
Sample Output
Prime 2
Source
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define bignum unsigned long long
using namespace std;
//求a,b的最大公约数
bignum gcd(bignum a,bignum b)
{
return b==0?a:gcd(b,a%b);
}
//求a*b%c,因为a,b很大,所以要先将b写成二进制数,再加:例如3*7=3*(1+2+4);
bignum mulmod(bignum a,bignum b,bignum c)
{
bignum cnt=0,temp=a;
while(b)
{
if(b&1) cnt=(cnt+temp)%c;
temp=(temp+temp)%c;
b>>=1;
}
return cnt;
}
//求a^b%c,再次将b写成二进制形式,例如:3^7=3^1*3^2*3^4;
bignum powmod(bignum a,bignum b,bignum c)
{
bignum cnt=1,temp=a;
while(b)
{
if(b&1) cnt=mulmod(cnt,temp,c);//cnt=(cnt*temp)%c;
temp=mulmod(temp,temp,c);//temp=(temp*temp)%c;
b>>=1;
}
return cnt;
}
//Miller-Rabin测试n是否为素数,1表示为素数,0表示非素数
int pri[10]={2,3,5,7,11,13,17,19,23,29};
bool Miller_Rabin(bignum n)
{
if(n<2) return 0;
if(n==2) return 1;
if(!(n&1)) return 0;
bignum k=0,m;
m=n-1;
while(m%2==0) m>>=1,k++;//n-1=m*2^k
for(int i=0;i<10;i++)
{
if(pri[i]>=n) return 1;
bignum a=powmod(pri[i],m,n);
if(a==1) continue;
int j;
for(j=0;j<k;j++)
{
if(a==n-1) break;
a=mulmod(a,a,n);
}
if(j<k) continue;
return 0;
}
return 1;
}
//pollard_rho 大整数分解,给出n的一个非1因子,返回n是为一次没有找到
bignum pollard_rho(bignum C,bignum N)
{
bignum 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 = (mulmod(X, X, N) + N - C) % N;
}while (Y != X);
return N;
}
//找出N的最小质因数
bignum rho(bignum N)
{
if (Miller_Rabin(N)) return N;
do
{
bignum T = pollard_rho(rand() % (N - 1) + 1, N);
if (T < N)
{
bignum A, B;
A = rho(T);
B = rho(N / T);
return A < B ? A : B;
}
}
while(1);
}
int main ()
{
srand(time(NULL));
bignum n, ans;
int ci;scanf( "%d", &ci );
while (ci--)
{
cin>>n;
ans=rho(n);
if(ans==n)
{
printf("Prime/n");
}
else
{
cout<<ans<<endl;
}
}
return 0;
}
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define bignum unsigned long long
using namespace std;
//求a,b的最大公约数
bignum gcd(bignum a,bignum b)
{
return b==0?a:gcd(b,a%b);
}
//求a*b%c,因为a,b很大,所以要先将b写成二进制数,再加:例如3*7=3*(1+2+4);
bignum mulmod(bignum a,bignum b,bignum c)
{
bignum cnt=0,temp=a;
while(b)
{
if(b&1) cnt=(cnt+temp)%c;
temp=(temp+temp)%c;
b>>=1;
}
return cnt;
}
//求a^b%c,再次将b写成二进制形式,例如:3^7=3^1*3^2*3^4;
bignum powmod(bignum a,bignum b,bignum c)
{
bignum cnt=1,temp=a;
while(b)
{
if(b&1) cnt=mulmod(cnt,temp,c);//cnt=(cnt*temp)%c;
temp=mulmod(temp,temp,c);//temp=(temp*temp)%c;
b>>=1;
}
return cnt;
}
//Miller-Rabin测试n是否为素数,1表示为素数,0表示非素数
int pri[10]={2,3,5,7,11,13,17,19,23,29};
bool Miller_Rabin(bignum n)
{
if(n<2) return 0;
if(n==2) return 1;
if(!(n&1)) return 0;
bignum k=0,m;
m=n-1;
while(m%2==0) m>>=1,k++;//n-1=m*2^k
for(int i=0;i<10;i++)
{
if(pri[i]>=n) return 1;
bignum a=powmod(pri[i],m,n);
if(a==1) continue;
int j;
for(j=0;j<k;j++)
{
if(a==n-1) break;
a=mulmod(a,a,n);
}
if(j<k) continue;
return 0;
}
return 1;
}
//pollard_rho 大整数分解,给出n的一个非1因子,返回n是为一次没有找到
bignum pollard_rho(bignum C,bignum N)
{
bignum 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 = (mulmod(X, X, N) + N - C) % N;
}while (Y != X);
return N;
}
//找出N的最小质因数
bignum rho(bignum N)
{
if (Miller_Rabin(N)) return N;
do
{
bignum T = pollard_rho(rand() % (N - 1) + 1, N);
if (T < N)
{
bignum A, B;
A = rho(T);
B = rho(N / T);
return A < B ? A : B;
}
}
while(1);
}
int main ()
{
srand(time(NULL));
bignum n, ans;
int ci;scanf( "%d", &ci );
while (ci--)
{
cin>>n;
ans=rho(n);
if(ans==n)
{
printf("Prime/n");
}
else
{
cout<<ans<<endl;
}
}
return 0;
}