题目链接: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;
}