整数因子分解算法
奇葩的算法
View Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #define LL unsigned long long using namespace std; LL p[10] = { 2,3,5,7,11,13,17,19,23,29 },num[100],ans,sq; int cnt; LL Multi( LL a, LL b ,LL n ) { 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 ) { 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 ) ) { k ++ ; m >>= 1; } for( int i = 0; i < 10; 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; LL i = 1,k=2,d; x = y = abs( rand() )%(n-1) + 1; while( c == 0 || c== 2 ) c = abs( 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 ) + c)%n; }while( x != y ); return n; } void Pallord_Min( LL n ) { if( n == 1 ) return ; if( Miller_rabin( n ) ) { num[cnt++] = n; return ; } LL p = Pallord( n ); Pallord_Min( p ); Pallord_Min( n/p ); } void Solve( int n ,LL val ) { if( n >= cnt ) { if( val > ans && val <= sq ) ans = val; return ; } Solve( n + 1, val*num[n] ); Solve( n + 1 , val ); } bool cmp( LL a ,LL b ) { return a < b; } int main( ) { LL m, last, sum, t, ret; int T; scanf("%d", &T); while( T-- && scanf( "%I64u",&m ) ) { int flag = 0; if (m == 1) { printf("1 1\n"); continue; } cnt = last = sum = ret = t = 0; Pallord_Min( m ); sort( num , num + cnt ,cmp); for (int i = 1; i < cnt; ++i) { if (num[i] != num[i-1]) { flag = 1; break; } } if (!flag) { printf("1 %I64u\n", m/num[0]); continue; } for (int i = 0; i < cnt; ++i) { // printf("num[%d] = %I64u\n", i, num[i]); if (t == 0) { t = num[i]; ret++; continue; } if (num[i] == num[i-1]) { t *= num[i]; // printf("t = %I64u\n", t); } else { sum += t; // printf("t = %I64u, sum = %I64u\n", t, sum); t = num[i]; ++ret; } } printf("%I64u %I64u\n", ret, sum+t); } //system( "pause" ); return 0; }
posted on 2012-08-07 20:28 more think, more gains 阅读(420) 评论(0) 编辑 收藏 举报