这个题用到Miller_rabin与pallord算法:
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<ctime> #include<vector> #define LL long long using namespace std; LL p[10] = { 2,3,5,7,11,13,17,19,23,29 }; const LL Max = ( LL )1<<62; LL Multi( LL a ,LL b , LL n )//计算a*b { LL sum = 0; while( b ) { if( ( b&1 ) ) sum = ( sum + a )%n; a<<=1; b>>=1; if( a >= n ) a %= n; } return sum; } LL Quick_mod( LL a ,LL b ,LL n )//计算当d位奇数时a^b { LL sum = 1; while( b ) { if( ( b&1 ) ) sum = Multi( sum , a ,n ); a = Multi( a , a ,n ); b >>= 1; } return sum; } LL Miller_rabin( LL n )//米勒罗宾测试 { LL m = n -1,d,L; int k=0; if( n == 2 ) return true; if( n < 2 || !( n&1 )) return false; while( !( m&1 ) )//求n-1的2的次方 { k++ ; m >>= 1; } for( int i = 0 ; i < 9 ; i ++ ) { if( p[i] >= n ) return true; d = Quick_mod( p[i] , m ,n ); if( d == 1 ) continue; for( int j = 0; j < k ; j ++ ) { L = Multi( d , d ,n ); if( L == 1 && d != 1 && d != ( n- 1 ) ) return false; d = L; } if( d != 1 ) return false; } return true; } LL Gcd( LL a ,LL b ) { return b ==0 ? a : Gcd( b , a%b ); } LL Pallord( LL n ) { LL x,y,c=0,d,i=1,k=2; while(c==0 || c==2 ) c = abs( rand())%(n-1) + 1; x = y = (rand( )%( n-1 )) + 1; do { i++; d = Gcd( y + n - x, n ); if( d >1 && d < n ) return d; if( i == k ) { y = x; k <<= 1; } x = (Multi( x , x, n )+n-c )%n; }while( x != y ); return n; } LL Pallord_min( LL n ) { LL p,a,b; if( n == 1 ) return Max; if( Miller_rabin( n ) ) return n;//如果n为素数就返回 p = Pallord( n );//如果不是继续分解 a = Pallord_min( p );//继续分解p; b = Pallord_min( n / p ); return a < b ? a:b; //返回最小的质因子 } int main( ) { LL num; int Case; while( scanf( "%d",&Case )==1 ) { while( Case-- ) { scanf( "%I64d",&num ); if( Miller_rabin( num ) ) puts( "Prime" ); else printf( "%I64d\n",Pallord_min( num ) ); } } //system( "pause" ); return 0; }