Pollard_rho大数分解质因数

/*
T组输入,给定n,判断n是否为素数,若不为素数输出最大的质因数
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;
const int S = 20;//随机算法判定次数,S越大,判错概率越小
inline ll fp(ll b, ll p, ll mod) {
    ll ans = 1;
    while (p) {
        if (p & 1)
            ans = (lll)ans * b % mod;
        p >>= 1;
        b = (lll)b * b % mod;
    }
    return ans;
}
bool check(ll a, ll n, ll x, ll t) {
    ll ret = fp(a, x, n);
    ll last = ret;
    for (int i = 1; i <= t; i++) {
        ret = (lll)ret * ret % n;
        if (ret == 1 && last != 1 && last != n - 1)
            return 1;//合数
        last = ret;
    }
    if (ret != 1)
        return 1;
    return 0;
}
bool Miller_Rabin(ll n) {
    if (n < 2) return 0;
    if (n == 2) return 1;
    if ((n & 1) == 0) return 0;//偶数
    ll x = n - 1;
    ll t = 0;
    while ((x & 1) == 0) {
        x >>= 1;
        t++;
    }
    for (int i = 0; i < S; i++) {
        ll a = rand() % (n - 1) + 1;
        if (check(a, n, x, t))
            return 0;//合数
    }
    return 1;
}
ll factor[100];
int tol;//质因数的个数
ll gcd(ll a, ll b) {
    if (a == 0) return 1;
    if (a < 0) return gcd(-a, b);
    while (b) {
        ll t = a % b;
        a = b;
        b = t;
    }
    return a;
}
ll Pollard_rho(ll x, ll c) {
    ll i = 1, k = 2;
    ll x0 = rand() % x;
    ll y = x0;
    while (1) {
        i++;
        x0 = ((lll)x0 * x0 % x + c) % x;
        ll d = gcd(y - x0, x);
        if (d != 1 && d != x)
            return d;
        if (y == x0)
            return x;
        if (i == k) {
            y = x0;
            k += k;
        }
    }
}
//对n进行素因子分解
void findfac(ll n) {
    if (Miller_Rabin(n)) { //素数
        factor[++tol] = n;
        return;
    }
    ll p = n;
    while (p >= n)
        p = Pollard_rho(p, rand() % (n - 1) + 1);
    findfac(p);
    findfac(n / p);
}
int main() {
    srand(time(0));
    int T;
    scanf("%d", &T);
    while (T--) {
        ll n;
        scanf("%lld", &n);
        tol = 0;
        findfac(n);
        if (tol == 1)
            printf("Prime\n");
        else {
            ll ans = 0;
            for (int i = 1; i <= tol; i++) {
                ans = max(ans, factor[i]);
            }
            printf("%lld\n", ans);
        }
    }
    return 0;
}
posted @ 2020-12-03 19:37  UCPRER  阅读(141)  评论(0编辑  收藏  举报