zoukankan      html  css  js  c++  java
  • 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
    ");
            else {
                ll ans = 0;
                for (int i = 1; i <= tol; i++) {
                    ans = max(ans, factor[i]);
                }
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Notes | 基于医疗知识图谱的问答系统实践
    Notes | 知识图谱介绍与Neo4J实战
    从jvm源码看synchronized
    Kakfa基础
    volatile
    JVM垃圾收集器
    原码,反码,补码
    mini设计模式
    xshell提示采购解决方法
    应试必备算法
  • 原文地址:https://www.cnblogs.com/ucprer/p/14082312.html
Copyright © 2011-2022 走看看