int main(){ int t, i,j, cnt; ll tmpn, n, factor; scanf("%d", &t); while(t--){ scanf("%lld", &n); i=0, tmpn=n; while(millerIsPrime(n, 3)==0){ fac[i]=pollard_rho(n); n/=fac[i++]; } fac[i++]=n; cnt=i; qsort(fac, cnt, sizeof(ll), compare); for(i=0, j=0; i<cnt; i++){ div[j]=fac[i], powp[j]=1; while(fac[i]==fac[i+1]) i++, powp[j]++; j++; } cnt=j; printf("%lld = ", tmpn); for(i=0; i<cnt; i++) { printf("%lld", div[i]); if(powp[i]>1) printf("^%lld", powp[i]); if(i<cnt-1) printf(" * "); } printf("\n"); } return 0; }
void factorize(LL n, vector<LL> &divisor) { if (n == 1) return; if (prime_test(n)) divisor.push_back(n); else { LL d = n; while (d >= n) d = pollard_rho(n, rand() % (n - 1) + 1); factorize(n / d, divisor); factorize(d, divisor); } }
/* * pr_fact - print the factors of a number * * If the number is 0 or 1, then print the number and return. * If the number is < 0, print -1, negate the number and continue * processing. * * Print the factors of the number, from the lowest to the highest. * A factor will be printed numtiple times if it divides the value * multiple times. * * Factors are printed with leading tabs. */ static void pr_fact(BIGNUM *val) { const ubig *fact; /* The factor found. */ /* Firewall - catch 0 and 1. */ if (BN_is_zero(val) || BN_is_one(val)) errx(1, "numbers <= 1 aren't permitted."); /* Factor value. */ BN_print_dec_fp(stdout, val); putchar(':'); for (fact = &prime[0]; !BN_is_one(val); ++fact) { /* Look for the smallest factor. */ while (fact <= pr_limit) { if (BN_mod_word(val, (BN_ULONG)*fact) == 0) break; fact++; } /* Watch for primes larger than the table. */ if (fact > pr_limit) { #ifdef HAVE_OPENSSL BIGNUM *bnfact; bnfact = BN_new(); BN_set_word(bnfact, (BN_ULONG)*(fact - 1)); BN_sqr(bnfact, bnfact, ctx); if (BN_cmp(bnfact, val) > 0 || BN_is_prime(val, PRIME_CHECKS, NULL, NULL, NULL) == 1) { putchar(' '); BN_print_dec_fp(stdout, val); } else pollard_rho(val); #else printf(" %s", BN_bn2dec(val)); #endif break; } /* Divide factor out until none are left. */ do { printf(" %lu", *fact); BN_div_word(val, (BN_ULONG)*fact); } while (BN_mod_word(val, (BN_ULONG)*fact) == 0); /* Let the user know we're doing something. */ fflush(stdout); } putchar('\n'); }
void findFactor(bint n,int k) { if(n==1)return; if(miller_rabin(n, TIME)) { factor[++fac_top] = n; return; } bint p = n; while(p >= n) p = pollard_rho(p,k--); findFactor(p,k); findFactor(n/p,k); }
static void pollard_rho(BIGNUM *val) { BIGNUM *x, *y, *tmp, *num; BN_ULONG a; unsigned int steps_taken, steps_limit; x = BN_new(); y = BN_new(); tmp = BN_new(); num = BN_new(); a = 1; restart: steps_taken = 0; steps_limit = 2; BN_set_word(x, 1); BN_copy(y, x); for (;;) { BN_sqr(tmp, x, ctx); BN_add_word(tmp, a); BN_mod(x, tmp, val, ctx); BN_sub(tmp, x, y); if (BN_is_zero(tmp)) { #ifdef DEBUG printf(" (loop)"); #endif a++; goto restart; } BN_gcd(tmp, tmp, val, ctx); if (!BN_is_one(tmp)) { if (BN_is_prime(tmp, PRIME_CHECKS, NULL, NULL, NULL) == 1) { putchar(' '); BN_print_dec_fp(stdout, tmp); } else { #ifdef DEBUG printf(" (recurse for "); BN_print_dec_fp(stdout, tmp); putchar(')'); #endif pollard_rho(BN_dup(tmp)); #ifdef DEBUG printf(" (back)"); #endif } fflush(stdout); BN_div(num, NULL, val, tmp, ctx); if (BN_is_one(num)) return; if (BN_is_prime(num, PRIME_CHECKS, NULL, NULL, NULL) == 1) { putchar(' '); BN_print_dec_fp(stdout, num); fflush(stdout); return; } BN_copy(val, num); goto restart; } steps_taken++; if (steps_taken == steps_limit) { BN_copy(y, x); /* teleport the turtle */ steps_taken = 0; steps_limit *= 2; if (steps_limit == 0) { #ifdef DEBUG printf(" (overflow)"); #endif a++; goto restart; } } } }