1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <ctime> 5 #include <cstdlib> 6 #include <iostream> 7 using namespace std; 8 9 #define ll long long 10 const int S = 10; 11 ll ans; 12 13 ll gcd(ll a,ll b){ 14 if(a < 0) return gcd(-a , b); 15 if (b==0) return a; 16 return gcd(b , a%b); 17 } 18 19 ll multi_mod(ll a , ll b , ll k) //a*b%k 20 { 21 a %= k; 22 b %= k; 23 ll ret = 0; 24 //这里因为是长整数,for(i=0->b)循环一个个加太耗时,需要采用这种logn复杂度的方法 25 while(b){ 26 if(b & 1){ 27 ret += a; 28 ret %= k; 29 } 30 a <<= 1; 31 a %= k; 32 b >>= 1; 33 } 34 return ret; 35 } 36 37 ll pow_mod(ll a, ll b, ll mod) //求(a^b)%mod 38 { 39 if(b == 1) return a%mod; 40 int bit[1000] , t = 0; 41 while(b){ 42 bit[t++] = b&1; 43 b>>=1; 44 } 45 //类似矩阵快速幂 46 ll ret = 1; 47 for(int i = t-1 ; i>=0 ; i--){ 48 ret = multi_mod(ret , ret , mod); 49 if(bit[i]) ret = multi_mod(ret , a , mod); 50 } 51 return ret; 52 } 53 //n = x*2^t , 这里以a为底 , 检验n是否为合数 54 bool check(ll a , ll n , ll x , ll t) 55 { 56 ll ret = pow_mod(a , x , n); 57 ll last = ret; //last记录上一次的数据,保证最后结果模1时,检查到last不为n-1或1,就表示为合数 58 for(int i = 1 ; i<=t ; i++){ 59 ret = multi_mod(ret,ret,n); 60 if(ret == 1 && last!=1 && last!=n-1) return true; 61 last = ret; 62 } 63 //始终无法找到余数为1的结果,则表示n为合数 64 if(ret!=1) return true; 65 return false; 66 } 67 //n为合数返回true 68 bool miller_rabin(ll n) 69 { 70 ll x = n-1 , t = 0; 71 while((x&1) == 0){ 72 x>>=1; 73 t++; 74 } 75 bool flag = true; 76 77 //保证最后得到的 x^2 mod p = 1 只有x=1或x=p-1两个解,才满足二次探测,否则有其他解就直接证明不是素数 78 if(t >= 1 && (x&1)){ 79 //miller_robin是一种取随机测试数据的算法,这里S=20,给定20组测试数据,当然数据组数越多,正确率越大 80 for(int i = 0 ; i<S ; i++){ 81 ll a = rand()%(n-1)+1; 82 //二次探测在check中检测 83 if(check(a,n,x,t)){ 84 flag = true; 85 break; 86 } 87 flag = false; 88 } 89 } 90 if(!flag || n==2) 91 return false; 92 else return true; 93 } 94 95 //长整数利用随机数找到其中一个因子 96 ll Pollard_rho(ll x,ll c){ 97 ll i=1,x0=rand()%x,y=x0,k=2; 98 while (1){ 99 i++; 100 x0=(multi_mod(x0,x0,x)+c)%x; 101 ll d=gcd(y-x0,x); 102 if (d!=1&& d!=x){ 103 return d; 104 } 105 if (y==x0) return x; 106 if (i==k){ 107 y=x0; 108 k+=k; 109 } 110 } 111 } 112 113 //不断利用Pollard_rho递归来查找到n的所有素数因子 114 void find_factor(ll n) 115 { 116 if(!miller_rabin(n)){ 117 ans = min(ans , n); 118 return; 119 } 120 ll p = n; 121 while(p >= n) 122 p = Pollard_rho(p , rand() % (n-1) + 1); 123 find_factor(p); 124 find_factor(n / p); 125 } 126 127 int main() 128 { 129 srand(time(NULL)); 130 int T; 131 scanf("%d" , &T); 132 while(T--){ 133 ll n; 134 scanf("%lld" , &n); 135 bool flag = miller_rabin(n); 136 if(!flag) printf("Prime "); 137 else{ 138 ans = n; 139 find_factor(n); 140 141 printf("%lld " , ans); 142 } 143 } 144 return 0; 145 }