素数测试以及因数分解的模版 Miller-Rabin + Pollard-rho
#include <iostream> #include <ctime> #include <cstdlib> #include <cmath> #include <algorithm> #define TIME 12 #define C 240 #define MAX (pow(2.0,60)) using namespace std; long long MIN; long long gcd(long long a,long long b) { if(!b) return a; return gcd(b,a%b); } long long mod_mult(long long a,long long b,long long c)//计算(a*b) mod c { long long r=0; while(b>0) { if(b & 1) r=(r+a)%c; a=(a+a)%c; b>>=1; } return r; } long long mod_pow(long long a,long long b,long long c) { long long r=1; while(b) { if(b & 1) r=mod_mult(r,a,c); a=mod_mult(a,a,c); b>>=1; } return r; } bool witness(long long a,long long n) { long long m,x,y; int i,j=0; m=n-1; while(m%2==0) { m>>=1; j++; } x=mod_pow(a,m,n); for(i=1;i<=j;i++) { y=mod_pow(x,2,n); if((y==1) && (x!=1) && (x!=n-1)) return 1; x=y; } if(y!=1) return 1; return 0; } bool miller_rabin(int times,long long n) { long long a; int i; if(n==1) return 0; if(n==2) return 1; if(n%2==0) return 0; srand(time(NULL)); for(i=1;i<=times;i++) { a=rand()%(n-1)+1; if(witness(a,n)) return 0; } return 1; } long long pollard_rho(long long n,long long c) { int i=1; long long x=rand()%n,y=x; int k=2; do { i++; long long d=gcd(n+y-x,n); if(d>1 && d<n) return d; if(i==k) { y=x; k*=2; } x=(mod_mult(x,x,n)+n-c)%n; }while(y!=x); return n; } void bsearch(long long n,int c) { long long m; if(n==1) return ; if(miller_rabin(TIME,n)) { if(n<MIN) MIN=n; return ; } m=n; while(m==n) m=pollard_rho(n,c--); bsearch(m,c); bsearch(n/m,c); } int main() { int t; long long n; scanf("%d",&t); while(t--) { scanf("%lld",&n); MIN=MAX; if(miller_rabin(TIME,n)) puts("Prime"); else { bsearch(n,C); printf("%lld\n",MIN); } } return 0; }