long long质因数分解模板

时间:2019-08-21
本文章向大家介绍long long质因数分解模板,主要包括long long质因数分解模板使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
const ll inf = 1e18;
const ll maxn = 1e18 + 4;
typedef long double ld;

const int N = 65, P = 5, prime[P] = {2, 3, 7, 61, 24251};
ll n, pn;
ll f[N];

inline ll mul(ll a, ll b, ll p) {
    a %= p;
    b %= p;
    ll c = (ld)a*b/p;
    c = a * b - c * p;
    if(c < 0) c += p; else
        if(c > p) c -= p;
    return c;
}
inline ll ksm(ll x, ll y, ll p) {
    ll s = 1;
    while(y) {
        if(y & 1) s = mul(s,x,p);
        x = mul(x, x, p);
        y >>= 1;
    }
    return s;
}
inline ll twice(ll a, ll p) {
    ll d = p-1;
    int t = 0;
    while(!(d & 1)) d >>= 1, t++;
    ll x, y;
    x = y = ksm(a, d, p);
    while(t--) {
        y = mul(x, x, p);
        if(y == 1 && (x ^ 1) && (x ^ p)-1) return 0;
        x = y;
    }
    return y;
}
inline ll random(ll up) {
    return (ll)rand()*rand()%up;
}
ll gcd(ll x, ll y) {
    return !y?x:gcd(y, x % y);
}
inline ll abs(ll x, ll y) {
    return x < y? y - x: x - y;
}
inline bool Miller_Rabin(ll x) {
    for(int i = 0; i < P; i++) {
        if(x == prime[i]) return true;
        if(twice(prime[i], x)^1) return false;
    }
    return true;
}
inline ll trans(ll x, ll y, ll z) {
    return (mul(x, x, z) + y) % z;
}
void Pollard_rho(ll m) {
    if(Miller_Rabin(m)) {
        f[++f[0]] = m;
        return;
    }
    ll x1 = 0, x2 = 0, c = 0, p = 1;
    while(p == 1 || p == m) {
        x1 = trans(x1, c, m);
        x2 = trans(trans(x2, c, m), c, m);
        while(x1 == x2) {
            c = random(m);
            x1 = x2 = random(m);
            x2 = trans(x2, c, m);
        }
        p = gcd(abs(x1 - x2), m);
    }
    Pollard_rho(p);
    Pollard_rho(m/p);
}


int main() {
    ll n; cin >> n;
    if(n == 1){
        cout << "NO" << endl;
        return 0;
    }
    srand(time(NULL));
    Pollard_rho(n);
    sort(f + 1, f + 1 + f[0]);
    f[0] = unique(f + 1, f + 1 + f[0]) - (f + 1);
    for(int i = 1; i <= f[0]; i++){ //输出素因子个数
        cout << f[i] << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/philo-zhou/p/11390842.html