RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试。
Pollard_rho算法的大致流程是 先判断当前数是否是素数(Miller_rabin)了,如果是则直接返回。如果不是素数的话,试图找到当前数的一个因子(可以不是质因子)。然后递归对该因子和约去这个因子的另一个因子进行分解。
https://lunatic.blog.csdn.net/article/details/104218095
https://blog.csdn.net/maxichu/article/details/45459533
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> typedef long long ll ; #define int ll #define mod 1000000007 #define gcd __gcd #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //ll lcm(ll a , ll b){return a*b/gcd(a,b);} ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define SC scanf #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 using namespace std; const int N = 1e6+100; const int maxn = 2e5+9; int pr; int quickmul(int a , int b , int m){ return ((a * b - (ll)(long double)(a/m*b) * m)+m)%m ; } int quickpow(int a , int b , int m){ int ans = 1 ; while(b){ if(b&1) ans = quickmul(ans , a , m) ; b >>= 1 ; a = quickmul(a , a , m); } return ans ; } inline ll gcd(ll a, ll b) { //听说二进制算法特快 if (!a) return b; if (!b) return a; int t = __builtin_ctzll(a | b); a >>= __builtin_ctzll(a); do { b >>= __builtin_ctzll(b); if (a > b) { ll t = b; b = a, a = t; } b -= a; } while (b); return a << t; } bool Miller_Rabin(int n){ if(n == 46856248255981ll || n < 2) return false; if(n == 2 || n == 3 || n == 7 || n == 61 || n == 24251) return true; if(!(n&1) || !(n%3) || !(n%61) || !(n%24251)) return false; int m = n - 1 , k = 0 ; while(!(m&1)) k++ , m>>=1 ;// 分解2^s * t = n - 1 rep(i , 1 , 20){ int a = rand() % (n - 1) + 1 , x = quickpow(a , m , n) , y; rep(j , 1 , k){ y = quickmul(x , x , n); if(y == 1 && x != 1 && x != n - 1) return false;//二次测探 x = y ; } if(y != 1) return false;//费马小定理 } return true; } ll Pollard_Rho(ll x) { ll n = 0, m = 0, t = 1, q = 1, c = rand() % (x - 1) + 1; for (ll k = 2;; k <<= 1, m = n, q = 1) { for (ll i = 1; i <= k; ++i) { n = (quickmul(n, n, x) + c) % x; q = quickmul(q, abs(m - n), x); } t = gcd(x, q); if (t > 1) return t; } } map<long long, int> m; void fid(ll n) { if (n == 1) return; if (Miller_Rabin(n)) { pr = max(pr, n); m[n]++; return; } ll p = n; while (p >= n) p = Pollard_Rho(p); fid(p); fid(n / p); } void solve(){ int n ; m.clear(); scanf("%lld", &n); pr = 0; fid(n); if (pr == n) puts("Prime"); else{ printf("%lld ", pr); for (map<long long, int>::iterator c = m.begin(); c != m.end();){ printf("%lld^%d", c->first, c->second); if ((++c) != m.end()) printf(" * "); } printf(" "); } } signed main() { //ios::sync_with_stdio(false); //cin.tie(0); cout.tie(0); int t ; cin >> t ; while(t--){ solve(); } }