题意:给你一个数,如果这个数是合数就输出它的最少因子
思路:套Pollard_rho算法模板
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
#define MAX ((long long)1<<61)
LL factor[200],cnt;
LL mini;
LL gcd(LL a,LL b) {
return (b==0)?a:gcd(b,a%b);
}
LL Mulmod(LL a,LL b,LL n) {
LL 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;
}
LL exp_mod(LL a,LL b,LL c){
LL k = 1;
while(b){
if(b&1)
k = Mulmod(k,a,c);
a = Mulmod(a,a,c);
b>>=1;
}
return k;
}
bool Miller_Rabin(LL n, LL times){
if(n==2)return 1;
if(n<2||!(n&1))return 0;
LL a, u=n-1, x, y;
int t=0;
while(u%2==0){
t++;
u/=2;
}
srand(100);
for(int i=0;i<times;i++){
a = rand() % (n-1) + 1;
x = exp_mod(a, u, n);
for(int j=0;j<t;j++){
y = Mulmod(x, x, n);
if ( y == 1 && x != 1 && x != n-1 )
return false; //must not
x = y;
}
if( y!=1) return false;
}
return true;
}
LL Pollard_Rho(LL n,LL c){
LL x,y,d,i=1,k=2;
y = x = rand() % (n-1) + 1;
while(1){
i++;
x = (Mulmod(x,x,n) + c)%n;
d = gcd((x-y+n)%n,n);
if(d>1&&d<n)
return d;
if(x==y)
return n;
if(i==k){
k<<=1;
y = x;
}
}
}
void Find_factor(LL n,LL c) {
if(n==1)
return;
if(Miller_Rabin(n,6)){
factor[cnt++] = n;
if(n<mini) mini=n;
return;
}
LL p = n;
LL k = c;
while(p>=n)
p = Pollard_Rho(p,c--);
Find_factor(p,k);
Find_factor(n/p,k);
}
int main(){
int t;
scanf("%d",&t);
LL n;
while(t--){
scanf("%lld",&n);
mini=MAX;
cnt=0;
if(Miller_Rabin(n,6)) puts("Prime");
else{
Find_factor(n,120);
printf("%lld\n",mini);
}
}
return 0;
}