ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Pollard_Rho 算法

2020-03-09 14:53:43  阅读:237  来源: 互联网

标签:return int while i64 Pollard 算法 Rho


Pollard_Rho

以下为分解最大质因子代码。

#include <ctime>
#include <iostream>

using i64 = long long;

#define DEBUG() std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl
#define ctz __builtin_ctzll

i64 gcd(i64 a, i64 b);
i64 pow(i64 a, i64 k, i64 p);
i64 mul(i64 a, i64 b, i64 p);
int Miller_Rabin(i64 n);
void Pollard_Rho(i64 n);

int t;
i64 n, MaxFactor = 1;

int main() {
    srand(time(0));
    
    scanf("%d", &t);
    while (t--)
        scanf("%lld", &n), MaxFactor = 1, Pollard_Rho(n),
        MaxFactor == n ? printf("Prime\n") : printf("%lld\n", MaxFactor);

    return 0;
}

i64 gcd(i64 a, i64 b) {
//  return b ? gcd(b, a % b) : a;
    int shift = ctz(a | b);
    b >>= ctz(b);
    while (a) {
        a >>= ctz(a);
        if (a < b) std::swap(a, b);
        a -= b;
    }
    return b << shift;
}
i64 pow(i64 a, i64 k, i64 p) {
    i64 t = 1;
    for (; k; a = mul(a, a, p), k >>= 1) if (k & 1) t = mul(t, a, p);
    return t;
}
i64 mul(i64 a, i64 b, i64 p) {
    i64 c = (a * b - (i64)((long double)a * b / p + 1e-9) * p) % p;
    return c < 0 ? c + p : c;
}

int Miller_Rabin(i64 n) {
    static const i64 P[] = { 2, 325, 9375, 28178, 450775, 9780504, 1795265022, 0 };
    if (n < 2) return 0;
    i64 m = n - 1, a, b; int k = 0;
    while (!(m & 1)) m >>= 1, ++k;
    for (int i = 0; P[i]; ++i) {
        if (!(a = P[i] % n)) return 1;
        a = b = pow(a, m, n);
        for (int j = 1; j <= k; ++j, a = b)
            if ((b = mul(a, a, n)) == 1 && a != 1 && a != n - 1) return 0;
        if (a != 1) return 0;
    }
    return 1;
}

void Pollard_Rho(i64 n) {
    if (n <= MaxFactor) return;
    if (n == 1 || Miller_Rabin(n)) { MaxFactor = n; return; }
    
    auto find = [](i64 n) {
        static const int LIM = 1 << 22;
        i64 x = rand() % n, y, z, w, c = rand() % (n - 1) + 1;
        for (int i = 1; i <= LIM; i <<= 1) {
            y = x, z = 1;
            for (int j = 1; j <= i; ++j) {
                x = (mul(x, x, n) + c) % n;
                z = mul(z, std::abs(x - y), n);
                if (j % 127 == 0 && (w = gcd(z, n)) > 1) return w;
            }
            if ((w = gcd(z, n)) > 1) return w;
        }
        return n;
    };
    i64 d;
    for (d = n; d == n; d = find(n));
    while (n % d == 0) n /= d;
    Pollard_Rho(d), Pollard_Rho(n);
}

标签:return,int,while,i64,Pollard,算法,Rho
来源: https://www.cnblogs.com/Ryedii-blog/p/12448697.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有