LG的数学计划----分解质因数(Pollard-Rho算法)

本文介绍了一种高效的质因数分解算法——Pollard-Rho算法,并通过对比暴枚算法突出其优越性。该算法利用随机化策略和特定的数论技巧寻找合数的非平凡因子。

1.对于我们朴素的求解质因数, 暴枚真是个好算法

好吧一样的就不给出代码了,

2.对于另一种神奇的算法Pollard-Rho算法

随机化算法, 与Miller robin有着密切联系, 可以先看一看两种算法都不难, 只是很神奇。。
这个算法也是一步步分解, 再递归求解, 但是它实现分解的过程非常奇妙, 我们如果在p中rand()分解, 这无疑是很愚蠢的。。。但是p又一定可以分解, 所以我们要while(1),
接下来是一个神奇的结论,
上面说过一个个试还不如暴枚, 那么我们就要优化,
取两个数, x1, x2, 看gcd(x2-x1, p)是否大于1, 是的话递归求解,
那么现在随中的几率更高了, 但是对于大数还是很慢, 所以我们要再优化,
那么对于x1, x2的求法就要讲究一下, 我们可以发现
采用这个求法

x2 = (x1*x1+c) % p;
这样是不是快了很多, 因为x2-x1的差重复的几率减小了
但是还是可能出现很背的情况, 你不换个c这破电脑不给你出来, 那我们就要想办法解决这组种子找不出解跳出来的情况,
我们发现 ,这样算会求出一个%p的循环节, 正是我们所需要的,它会走出一个神奇的圈!
就像这样

我们的目的是找到这个重复显然一个个存下来很麻烦, 我们用一种倍增的方法来解决这个问题(正确性我不会证感觉这样就好了), 每次*2当一次倍增完成后, 覆盖一次x1, x2
代码

#include <ctime>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define rep(i, s, t) for(int i = s; i <= t; ++i)
typedef long long ll;

ll H;
ll pls(ll a, ll b, ll p) {
    ll res = 0;
    for(; b; b >>= 1, a = (a+a)%p)
        if(b & 1) res = (res+a)%p;
    return res%p;
}

ll pow(ll a, ll b, ll p) {
    ll res = 1;
    for(; b; b >>= 1, a = pls(a, a, p))
        if(b & 1) res = pls(res, a, p)%p;
    return res % p;
}

bool M(ll p) {
    ll x[60] = {0}, s = 20;
    ll rest = p-1, t = 0;
    while(!(rest%2)) {
        t ++;
        rest >>= 1;
    }

    while(s--) {
        ll a = rand()%(p-1)+1;
        x[0] = pow(a, rest, p);
        rep(i, 1, t) {
            x[i] = pow(x[i-1], 2, p)%p;
            if(x[i] == 1) 
                if((x[i-1] != 1) && (x[i-1] != p-1)) return false;
        }
        if(x[t] ^ 1) return false;
    }
    return true;
}

ll gcd(ll a, ll b) {
    while(b) {
        ll t = a%b;
        a = b;
        b = t;
    }
    return a;
}

ll P(ll p) {
    ll c = rand()%(p-1)+1, x1 = rand()%(p-1)+1, x2 = x1;
    for(ll i = 2, k = 2; true; ++i) {
        x1 = (pls(x1, x1, p) + c)%p;
        ll G = gcd(p, (x2-x1+p)%p);
        if(G > 1 && G < p) return G;
        if(x2 == x1) return p;
        if(i == k) x2 = x1, k <<= 1;
    }
}

void solve(long long n) {
    if(n == 1) return;
    if(M(n)) {
        H = min(H , n);
        return;
    }
    long long p = n;
    while(p == n) p = P(p);
    solve(p);
    solve(n/p);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
    freopen("res.out", "w", stdout);
#endif
    int _;
    scanf("%d", &_);
    while(_--) {
        ll p;
        H = 1LL << 54;
        scanf("%lld", &p);
        solve(p);
        if(H ^ p)
            printf("%lld\n", H);
        else puts("Prime");
    }
    return 0;
}

其实这是一个裸题代码poj1811, 会写一篇code解释

<think>我们被要求解释Pollard-rho算法,并在最后提出3-5个相关问题。 根据历史对话,之前讨论了有限域上高次多项式求解的困难性,并提到Pollard-rho算法的时间复杂度为O(sqrt(p))。 因此,这里应该详细解释Pollard-rho算法,特别是它在离散对数问题或因数分解中的应用。 注意:Pollard-rho算法有两种主要应用:因数分解和求解离散对数。由于之前讨论的是离散对数问题(椭圆曲线),这里可以侧重离散对数的Pollard-rho。 回答结构: 1. 算法简介:是什么,解决什么问题。 2. 核心思想:随机游走、Floyd环检测、碰撞原理。 3. 算法步骤:伪代码或步骤描述。 4. 时间复杂度:O(sqrt(n)),其中n是群的阶。 5. 为何受模运算阻碍?在有限域上,算法依赖的碰撞原理仍然有效,但计算复杂度仍然很高。 注意:用户要求用中文回答,且最后必须输出“§§相关问题§§”并列出3-5个相关问题。</think>### Pollard-Rho 算法详解 Pollard-Rho 算法是一种概率型算法,主要用于解决以下两类问题: 1. **整数分解**:寻找大整数的非平凡因子 2. **离散对数问题**:在循环群中求解 \( a^x \equiv b \pmod{p} \) #### 核心原理 1. **随机游走与碰撞检测**: - 通过函数 \( f(x) = (x^2 + c) \mod n \) 生成伪随机序列 - 利用 Floyd 环检测算法(龟兔赛跑)寻找序列中的碰撞点 - 当 \( x_i \equiv x_j \pmod{d} \) 但 \( x_i \neq x_j \pmod{n} \) 时,\( \gcd(x_i - x_j, n) \) 给出因子 2. **离散对数求解**: - 将群分解为三个子集 \( S_0, S_1, S_2 \) - 定义迭代函数: \[ x_{i+1} = \begin{cases} g \cdot x_i & \text{if } x_i \in S_0 \\ x_i^2 & \text{if } x_i \in S_1 \\ h \cdot x_i & \text{if } x_i \in S_2 \end{cases} \] - 当检测到 \( x_i = x_j \) 时,解方程 \( g^a h^b = g^{a'} h^{b'} \) 得离散对数 #### 算法步骤(整数分解版) ```python import math def pollard_rho(n): if n % 2 == 0: # 处理偶数 return 2 x = 2; y = 2; d = 1 c = random.randint(1, n-1) # 随机常数 f = lambda x: (x*x + c) % n while d == 1: x = f(x) # 乌龟前进一步 y = f(f(y)) # 兔子前进两步 d = math.gcd(abs(x - y), n) return d if d != n else "失败" ``` #### 时间复杂度与局限性 1. **时间复杂度**: - 整数分解:\( O(\sqrt{p}) \),其中 \( p \) 是 \( n \) 的最小质因子 - 离散对数:\( O(\sqrt{m}) \),其中 \( m \) 是循环群的阶 2. **关键局限**: - **概率型算法**:可能多次运行才能得到结果 - **大质数瓶颈**:当 \( p > 10^{20} \) 时,\( \sqrt{p} \) 次迭代仍不可行 - **量子威胁**:Shor算法可在多项式时间内解决相同问题 #### 实际应用场景 | 问题类型 | 适用参数范围 | 典型计算时间(CPU) | |----------------|-------------------|---------------------| | 分解64位整数 | \( n < 10^{19} \) | < 1秒 | | 分解128位RSA | \( n \approx 2^{128} \) | > 1000年 | | 椭圆曲线离散对数 | 群阶 \( |G| > 2^{128} \) | 宇宙年龄的 \( 10^8 \) 倍 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值