Pollard's Rho 学习笔记

找出因子

给定正整数 \(n\),求出 \(n\) 的一个因子 \(k\)

对于所有数据,\(1\leq n\leq10^{18}\)

Solution

先用 Miller-Rabin 把 \(n\) 为素数的情况判了。

根据生日悖论,生成 \(\sqrt{\dfrac{\pi n}{2}}\)\(1\sim n\) 的数就期望得到两个相等的数,下文将 \(\sqrt{\dfrac{\pi n}{2}}\) 看作 \(\sqrt{n}\)

一个合数 \(n\) 肯定有一个 \(\le \sqrt{n}\) 的因子 \(d\),那么生成 \(\mathcal{O}(\sqrt[4]{n})\) 个数就期望得到两个数 \(x\equiv y\pmod d\)

\(x\equiv y\pmod d\Rightarrow x-y\equiv0\pmod d\Rightarrow d\mid\gcd(|x-y|,n)\),所以 \(\gcd(|x-y|,n)\) 就是 \(n\) 的一个因子。考虑枚举 \(x,y\),可以做到 \(\mathcal{O}(\sqrt{n}\log n)\)

但是 Pollard 定义了一个随机数生成器 \(f(x)=x^2+c\),并设置了一个数列 \(\{a_n\}\)\(a_0=k\)\(a_{i+1}=f(a_i)\),其中 \(k,c\) 是随机的参数。

为什么要这样呢?因为这样的数列有一个性质:如果 \(a_{i}-a_{j}\equiv 0\pmod d\),则:

\[a_{i+1}-a_{j+1}=a_{i}^2-a_{j}^2=(a_i+a_j)(a_i-a_j)\equiv 0\pmod d \]

也就是说我们枚举的 \(a_{i},a_{j}\) 最好 \(j-i\) 是不同的。并且,\(\{a_n\}\) 是有环的。

我们可以使用 Floyd 判圈算法,定义 \(s=a_{k},t=a_{2k+1}\),若 \(s=t\) 则说明进入环中,直接返回重新选择 \(k,c\)。若某时刻 \(\gcd(|s-t|,n)\neq 1\) 则返回 \(\gcd(|s-t|,n)\) 作为一个因子。

时间复杂度

时间复杂度为 \(\mathcal{O}(n^{\frac{1}{4}}\log n)\),理由:
\(\gcd(|s-t|,n)\neq 1\) 意味着 \(s\equiv t\pmod d\)。设数列 \(b_{i}=a_{i}\mod d\),根据生日悖论,只要生成的序列足够随机,\(\{b_n\}\) 的环长期望为 \(\sqrt{d}\)。也就是说我们只需要期望 \(\mathcal{O}(\sqrt{d})\) 次就能找出一个因子。算上 gcd 的复杂度,\(\mathcal{O}(\sqrt{d}\log n)\leq\mathcal{O}(n^{\frac{1}{4}}\log n)\)

Code

LL floyd(LL n) {
	LL seed = rnd() % n, s, t;
	auto f = [&](LL x) { return (mul(x, x, n) + seed) % n; };
	s = t = rnd() % n, t = f(t);
	while (s != t) {
		LL d = __gcd(s - t + n, n);
		if (d != 1) return d;
		s = f(s), t = f(f(t));
	} 
	return 1;
}

分解质因数

给定 \(n\),将其分解质因数。有 \(T\) 组数据。

$对于所有数据,\(1\leq n\leq 10^{18}\)\(1\leq T\leq350\)

Solution

\(n\) 为质数则贡献答案,否则求出 \(n\) 的一个因子 \(d\),再递归求解 \(d\)\(n/d\)

时间复杂度 \(T(n)=n^{\frac{1}{4}}\log n+T(d)+T(n/d)\),根据主定理 \(T(n)=\mathcal{O}(n^{\frac{1}{4}}\log n)\)

Code

void PollardRho(LL n, map<LL, LL>& res) {
	LL d = 1;
	if (n == 1) return;
	if (MillerRabin(n)) { res[n] ++; return; }
	while (d == 1) d = floyd(n);
	PollardRho(d, res), PollardRho(n / d, res);
}
posted @ 2023-06-22 08:59  喵仔牛奶  阅读(33)  评论(0)    收藏  举报