米勒罗宾,素数探测
于是把p-1分解成 2 k ∗ t 2^k*t 2k∗t
从t开始往上自乘,每次指数*2,直到 2 k 2^k 2k
如果中间有不满足②的情况,为合数
最后再判断是否等于1(条件①)
用十个质数筛一筛就很稳,5个也行
筛质因子的
先判断要处理的数是不是质数(Miller-rabin)
不是的话每次随机一个数(用数列 f ( i ) = f ( i − 1 ) ∗ f ( i − 1 ) + c ( m o d x ) f_{(i)}=f_{(i-1)}*f_{(i-1)}+c \pmod x f(i)=f(i−1)∗f(i−1)+c(modx)两项的差)判断他和x的gcd是否不为1和n,可以的话递归处理
复杂度 O ( n 1 4 ) O(n^{\frac{1}{4}}) O(n41)
#include
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define ll __int128
#pragma GCC diagnostic error "-std=c++14"
#pragma GCC target("avx")
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
ll test[15]={0,2,61,23,37};
inline ll read(){
ll x=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch==EOF) return -1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x;
}
ll x;
inline ll quick_pow(ll a,ll b,ll mod){
ll na=1;
while(b){
if(b&1) na=(na*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return na;
}
inline ll MB(ll now){
if(now==1) return 0;
ll t=now-1,k=0;
while(!(t&1)) k++,t>>=1;
rep(i,1,4){
if(now==test[i]) return 1;
ll a=quick_pow(test[i],t,now),tmp=a;
rep(j,1,k){
tmp=(a*a)%now;
if(tmp==1&&a!=1&&a!=now-1) return 0;
a=tmp;
}
if(a!=1) return 0;
}
return 1;
}
inline ll gcd(ll a,ll b){
if(b==0) return a;
else return gcd(b,a%b);
}
void out (ll x){
if(x>9) out(x/10);
putchar(x%10+'0');
}
inline ll abss(ll aa){
return aa>0?aa:-aa;
}
inline ll Irand(ll x){
return (ll)((rand()<<15^rand())<<30^(rand()<<15^rand()))%x;
}
ll ans=0;
inline ll get(ll x){
register ll c=Irand(x) ;
register ll t1=Irand(x),t2=t1*t1%x+c ;
register ll dif=t1>t2?(t1-t2):(t2-t1),G=gcd(x,dif) ;
while (G == 1){
t1=t1*t1%x+c;if (t1>=x) t1%=x;
t2=t2*t2%x+c;t2=t2*t2%x+c;if (t2>=x) t2%=x;
dif=t1>t2?(t1-t2):(t2-t1),G=gcd(x,dif);
}
return G ;
}
inline void work(ll x){
if(x<=ans) return;
if(MB(x)){
ans=ans>x?ans:x;
return;
}
ll y=x;
while(y==x) y=get(x);
while(x%y==0){
x/=y;
}
work(y);work(x);
}
ll n;
int main(){
n=read();
for(register int i=1;i<=n;i++){
x=read();
if(MB(x)) printf("Prime\n");
else{
ans=0;
work(x);
out(ans),putchar(10);
}
}
return 0;
}