Prime Test
Time Limit: 6000MS | Memory Limit: 65536K |
Total Submissions: 17747 | Accepted: 3644 |
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
这道题就是miiler_rabin素数测试和pollard_rho质因子分解的标准模板题。。。第一次做这样的题,这道题我是参照网上别人的代码写的,作为学习,当做模板学习了.....
代码:
语言:c++
#include<ctime>
#include<iostream>
using namespace std;
long long factor[100],fac_top = -1;
//计算两个数的gcd
long long gcd(long long a,long long b)
{
if(a==0)
return b;
long long c;
while(b!=0)
{
c=b;
b=a%b;
a=c;
}
return a;
}
//ret = (a*b)%n (n<2^62)
long long muti_mod(long long a,long long b,long long n)
{
long long exp = a%n, res = 0;
while(b)
{
if(b&1)
{
res += exp;
if(res>n) res -= n;
}
exp <<= 1;
if(exp>n)
exp -= n;
b>>=1;
}
return res;
}
// ret = (a^b)%n
long long mod_exp(long long a,long long p,long long m)
{
long long exp=a%m, res=1; //
while(p>1)
{
if(p&1)//
res=muti_mod(res,exp,m);
exp = muti_mod(exp,exp,m);
p>>=1;
}
return muti_mod(res,exp,m);
}
//miller-rabin法测试素数, time 测试次数
bool miller_rabin(long long n, long long times)
{
if(n==2)return 1;
if(n<2||!(n&1))return 0;
long long a, u=n-1, x, y;
int t=0;
while(u%2==0){
t++;
u/=2;
}
srand(time(0));
for(int i=0;i<times;i++)
{
a = rand() % (n-1) + 1;
x = mod_exp(a, u, n);
for(int j=0;j<t;j++)
{
y = muti_mod(x, x, n);
if ( y == 1 && x != 1 && x != n-1 )
return false; //must not
x = y;
}
if( y!=1) return false;
}
return true;
}
long long pollard_rho(long long n,int c)
{//找出一个因子
long long x,y,d,i = 1,k = 2;
srand(time(0));
x = rand()%(n-1)+1;
y = x;
while(true) {
i++;
x = (muti_mod(x,x,n) + c) % n;
d = gcd(y-x, n);
if(1 < d && d < n)return d;
if( y == x) return n;
if(i == k) {
y = x;
k <<= 1;
}
}
}
void findFactor(long long n,int k)
{//二分找出所有质因子,存入factor
if(n==1)return;
if(miller_rabin(n, 10))
{
factor[++fac_top] = n;
return;
}
long long p = n;
while(p >= n)
p = pollard_rho(p,k--);//k值变化,防止死循环
findFactor(p,k);
findFactor(n/p,k);
}
int main()
{
long long t,n,min;
cin>>t;
while(t--)
{
cin>>n;
fac_top = min = -1;
if(miller_rabin(n,10))
cout<<"Prime"<<endl;
else
{
findFactor(n,107);
for(int i=0;i<=fac_top;i++){
if(min<0||factor[i]<min)
min = factor[i];}
cout<<min<<endl;
}
}
return 0;
}