任务描述
本关任务:给出一个大整数,请您判断它是否为素数。
编程要求
根据提示,在右侧编辑器补充代码。
测试说明
输入说明 第一行给出测试用例的个数 T
(1<=T<=20
),接下来的 T
行每行给出一个整数 N
(2<=N<=254
)。
输出说明 对于每个测试用例,如果N是素数,则输出单词“Prime
”;否则输出N的最小素数因子。
平台会对你编写的代码进行测试:
测试输入: 2
5
10
预期输出: Prime
2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx=1e6+7,times=11;
ll a[maxx],cnt,minn=1e18,c=201;
ll random(ll n)
{
return (ll)((double)rand()/RAND_MAX*n+0.5);
}
ll multi(ll a,ll b,ll mod)
{
ll ans=0;
while(b)
{
if(b&1)
ans=(ans+a)%mod;
b>>=1;
a=(a<<1)%mod;
}
return ans;
}
ll qpow(ll a,ll b,ll mod)
{
ll ans=1;
while(b)
{
if(b&1)
ans=multi(ans,a,mod);
a=multi(a,a,mod);
b>>=1;
}
return ans;
}
bool witness(ll a,ll mod)
{
ll m=mod-1;
int j=0;
while(!(m&1))
{
j++;
m>>=1;
}
ll x=qpow(a,m,mod);
if(x==1||x==mod-1)
return 0;
while(j--)
{
x=x*x%mod;
if(x==mod-1)
return 0;
}
return 1;
}
bool miller_rabin(ll n)
{
if(n<2) return 0;
if(n==2) return 1;
if(!(n&1)) return 0;
for(int i=1;i<=times;i++)
{
ll a=random(n-2)+1;
if(witness(a,n)) return 0;
}
return 1;
}
ll pollard_rho(ll n,ll c)
{
ll x,y,d,i=1,k=2;
x=random(n-1)+1;
y=x;
while(1)
{
i++;
x=(multi(x,x,n)+c)%n;
d=__gcd(y-x,n);
if(1<d&&d<n)
return d;
if(x==y)
return n;
if(i==k)
y=x,k<<=1;
}
}
void finds(ll n,ll k)
{
if(n==1) return;
if(miller_rabin(n))
{
a[++cnt]=n;
if(n<minn)
minn=n;
return;
}
ll p=n;
while(p>=n)
p=pollard_rho(p,k--);
finds(p,k);
finds(n/p,k);
}
int main()
{
ll n,t;
cin>>t;
while(t--)
{
minn=0x3f3f3f3f;
cin>>n;
if(miller_rabin(n))
cout<<"Prime"<<endl;
else
{
finds(n,c);
cout<<minn<<endl;
}
}
}