质因数分解模版

普通版本的质因数分解:时间复杂度为 \(O(\sqrt{n})\),可以处理 \(n=1e10\)

struct Avg{
    i64 N;
    vector<i64> preim;
    vector<i64> cnt;
    Avg(i64 N_) {
        N = N_;
        for (i64 i = 2; i <= N / i; i++) {
            i64 sum = 0;
            while (N % i == 0) sum++, N /= i;
            if (sum) preim.push_back(i);
            if (sum) cnt.push_back(sum);
        }
        
        if (N > 1) {
            preim.push_back(N);
            cnt.push_back(1);
        }
    }
};

稍微处理后的质因数分解:时间复杂度为 \(O(\frac{2\sqrt n}{ln(n)})\) ,最大可以处理 \(n=1e16\) 内的数。

struct pre{
    int N;
    vector<i64> preim;
    vector<i64> a;
    pre(int N_) : a(N_ + 1) {
        N = N_;
        for (i64 i = 2; i <= N; i++) {
            if (!a[i]) {
                a[i] = i;
                preim.push_back(i);
            }
            for (auto p : preim) {
                if (i * p > N) break;
                a[i * p] = p;
                if (a[i] == p) {
                    break;
                }
            }
        }
    }
};

pre t(M + 1);

struct Avg{
    i64 N;
    vector<i64> preim;
    vector<i64> cnt;
    Avg(i64 N_) {
        N = N_;
        for (auto p : t.preim) {
            if (p * p > N) break;
            i64 sum = 0;
            while (N % i == 0) sum++, N /= i;
            if (sum) preim.push_back(i);
            if (sum) cnt.push_back(sum);
        }
        
        if (N > 1) {
            preim.push_back(N);
            cnt.push_back(1);
        }
    }
};

\(Pollard-Rho\) 筛:时间复杂度为 \(O(n^{\frac{1}{4}})\),可以处理 \(n=1e18\) 内的数。(用的jls的板子,嘻嘻)

struct MR{
    inline i64 mul(i64 a, i64 b, i64 m) {
        return static_cast<i128>(a) * b % m;
    }
    
    inline i64 qp(i64 a, i64 b, i64 m) {
        i64 res = 1LL % m;
        for (; b; b >>= 1LL, a = mul(a, a, m))
            if (b & 1)
                res = mul(res, a, m);
        return res;
    }
    
    inline bool isprime(i64 n) {
        if (n < 2)
            return false;
        static constexpr i64 A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
        i64 s = __builtin_ctzll(n - 1);
        i64 d = (n - 1) >> s;
        for (auto a : A) {
            if (a == n)
                return true;
            i64 x = qp(a, d, n);
            if (x == 1 || x == n - 1)
                continue;
            bool ok = false;
            for (i64 i = 0; i < s - 1; ++i) {
                x = mul(x, x, n);
                if (x == n - 1) {
                    ok = true;
                    break;
                }
            }
            if (!ok)
                return false;
        }
        return true;
    }
};

MR t;

struct PR{
    inline i64 mul(i64 a, i64 b, i64 m) {
        return static_cast<i128>(a) * b % m;
    }
    
    inline vector<i64> factorize(i64 n) {
        vector<i64> p;
        function<void(i64)> f = [&](i64 n) {
            if (n <= 10000) {
                for (i64 i = 2; i * i <= n; ++i)
                    for (; n % i == 0; n /= i)
                        p.push_back(i);
                if (n > 1)
                    p.push_back(n);
                return;
            }
            if (t.isprime(n)) {
                p.push_back(n);
                return;
            }
            auto g = [&](i64 x) {
                return (mul(x, x, n) + 1) % n;
            };
            i64 x0 = 2LL;
            while (true) {
                i64 x = x0;
                i64 y = x0;
                i64 d = 1;
                i64 power = 1LL, lam = 0LL;
                i64 v = 1;
                while (d == 1) {
                    y = g(y);
                    ++lam;
                    v = mul(v, std::abs(x - y), n);
                    if (lam % 127LL == 0) {
                        d = std::gcd(v, n);
                        v = 1;
                    }
                    if (power == lam) {
                        x = y;
                        power *= 2LL;
                        lam = 0;
                        d = std::gcd(v, n);
                        v = 1;
                    }
                }
                if (d != n) {
                    f(d);
                    f(n / d);
                    return;
                }
                ++x0;
            }
        };
        f(n);
        sort(p.begin(), p.end());
        return p;
    }
};

PR st;
posted @ 2024-08-31 17:51  grape_king  阅读(146)  评论(0)    收藏  举报