Pollard_rho 因數分解


Int64以內Rabin-Miller強偽素數測試和Pollard 因數分解的算法實現

選取隨機數\(a\) 隨機數\(b\),檢查\(gcd(a - b, n)\)是否大於1,若大於1則\(a - b\)\(n\)的一個因數

實現1:floyd判環

利用多項式\(f(x)\)迭代出\({x_0, x_1, \dots, x_k}\)

設定\(x = y = x_0\)的初始值,選用多項式進行迭代,每次:\(x = f(x)\), \(y = f(f(y))\),即:\(x = x_k, y = x_{2k}\)\(x == y\)時出現循環

\(x = y = 2\)\(f(n) = n^2 + a\)

typedef long long ll;

ll mul_mod(ll a, ll b, ll m){
    ll ans = 0, exp = a;
    while(a >= m) a -= m;
    while(b){
        if(b & 1){
            ans += exp;
            while(ans >= m) ans -= m;
        }
        exp += exp;
        while(exp >= m) exp -= m;
        b >>= 1;
    }
    return ans;
}

ll pollard_rho(ll n, int a){
    ll x = 2, y = 2, d = 1;
    while(d == 1){
        x = mul_mod(x, x, n) + a;
        y = mul_mod(y, y, n) + a;
        y = mul_mod(y, y, n) + a;
        d = __gcd((x >= y ? x - y : y - x), n);
    }
    if(d == n) return pollard_rho(n, a + 1);
    return d;
}

實現2: brent判環(更高效)

不同於floyd每次計算\(x_k, x_{2k}\)進行判斷,brent每次只計算\(x_k\),當k是2的方冪時,\(y = x_k\),每次計算\(d = gcd(x_k - y, n)\)

typedef long long ll;

ll mul_mod(ll a, ll b, ll m){
    ll ans = 0, exp = a;
    while(a >= m) a -= m;
    while(b){
        if(b & 1){
            ans += exp;
            while(ans >= m) ans -= m;
        }
        exp += exp;
        while(exp >= m) exp -= m;
        b >>= 1;
    }
    return ans;
}

ll pollard_rho(ll n, int a){
    ll x = 2, y = 2, d = 1, k = 0, i = 1;
    while(d == 1){
        ++k;
        x = mul_mod(x, x, n) + a;
        d = __gcd(x >= y ? x - y : y - x, n);
        if(k == i){
            y = x;
            i <<= 1;
        }
    }
    if(d == n) return pollard_rho(n, a + 1);
    return d;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM