1.指数复杂度做法
1.1 暴力分解
检查所有
≤n 的因数,复杂度为
O(n)。
1.2 Pollard Rho
我们注意到对于值域为
[0,n−1] 的随机序列
a,
min{i∣∃j>i,ai=aj}=O(n),这时可以用
gcd(ai−aj,n) 提取出
n 的因子,且大概率是非平凡的。
随机取一个
c ,我们认为
ak+1=(ak2+c)modn 是随机的,因此这一过程期望进行
O(p) 次,时间复杂度
O(plogn) ,可以通过实现去掉
log 。
2.亚指数复杂度做法
以下的部分在 OI 中几乎没有用。
2.1 二次筛法
我们注意到,如果
a2≡b2(modn),那么
(a+b)(a−b)=kn,因此如果
n∤a−b 且
n∤a+b 则可以提取因数。
由于这一过程对
a,b 本身没有要求,因此可以将一些预先选出的
ai,bi 乘起来。设选出了
k 个
(ai,bi) 对,我们让
ai 为平方数,这样就只需要考虑
bi 。令
pi 为全体素数,
bi=p1e1p2e2…,只需要关注
eimod2 的值。
设
B 为
bi 因数中素数编号的最大值,则问题实际上等价于,每个
i 对应
0/1 向量
vi=[e1,e2…eB],要选出集合
S 使
i∈S∑vi≡0(mod2) 。由线性代数知识,我们可以知道至少有
2k−r−1 个解,其中
r 为
[v1…vk]T,有
r≤B,因此取
k=B+O(1) 即可以极大概率得到非平凡的解,使用高斯消元即可。
接下来的问题是,对于
B 如何快速生成较多的
(ai,bi) 对,且
bi 没有大于
pB 的因数。令
m=⌈n⌉,设
(ai′,bi′)=(i,(m+i)2−n),此时
bi′=O(in),因此可以用这个公式找到较多的
(ai′,bi′) 。
我们发现,对于
p∣n 有
bi+kp′≡(i+kp+m)2−n≡(i+m)2+2kp(i+m)−n≡bi′(modp),因此对满足
n 在模
p 下有二次剩余的
p,可以批量处理
(ai′,bi′)。对于
0≤i<p,若
(i+m)2−n≡0(modp) 则有
i≡±n−m(modp),需要用 Cipolla 算法求出二次剩余。
对这些
i ,我们有
bi+kp′ 均为
p 的倍数。对于所有
j≤B,枚举
pj ,计算二次剩余,将所有满足条件的
bi′ 除以
pj ,最后剩余
bi′=1 的
i 即满足没有大于
pB 的因数。可以证明,这样得到的
i 个数远大于 B。
复杂度是
Ln[21,1]=e(1+o(1))lnnlnlnn 的,实际上
1018 以内跑的比 Pollard-rho 慢,
1030 大概需要
0.5 秒。
2.2 椭圆曲线分解法
2.2.1 Pollard p-1 算法
我们注意到,若
p∣n 则有
xp−1≡1(modp) 对
p∤x 成立,因此我们可以用
gcd(xp−1−1,n) 提取
p 。但是我们不知道
p,所以我们取一个
B,令
k=q≤B∏q⌊logqB⌋,则若
p−1 的所有素因子都
≤B ,一定有
p−1∣k。
这样我们就可以使用
gcd(xk,n) 得到
p。对于一个特定的
B ,这样做的复杂度为
O(BlogBlog2n),在
p−1 较为光滑(质因子较小)时很有效。
一个例外是,对于一个
B,如果
n 的所有素因子
pi 都满足
pi−1 的所有素因子
≤B,此时
gcd(xk,n)=n ,我们无法提取因数。
我们定义一个以
P(n) 概率成功,复杂度为
T(n) 的算法的期望复杂度为
P(n)T(n),可以证明对于
B=na1,有
P(n)=a−a。因此这一算法的(期望)复杂度也为
e(1+o(1))lnnlnlnn 。这同时给出了这一类方法的复杂度下限。
2.2.2 椭圆曲线群
考虑形如
C:y2=x3+ax+b 的曲线,其中
4a3+27b2=0。
椭圆曲线群是定义在
C 上的群,运算
P+Q 为点
P 和点
Q 的连线与
C 的交点的对称点。一条直线与
C 只能有
1 或
3 个交点(记重数),而我们已经确定
2 个,因此
P+Q 存在且唯一。特别的,若
P=Q,我们定义连线为
C 过
P 的切线。
定义群中的
0 为无穷远点。我们让
P+0=P 恒成立,同时我们定义形如
P(x,y),Q(x,−y) 的直线交
C 于无穷远点。
实际计算中在模
p 意义下进行,这并不会改变定义。此时的
0 在分母为
p 的倍数时出现。
2.2.3 椭圆曲线分解法
我们发现 Pollard p-1 算法的效率依赖于
(Z/pZ)∗ 的结构,如果
p−1 包含较大的因子就会失效。考虑使用椭圆曲线群进行这一操作,由 Hasse 定理我们有
p+1−2p≤np≤p+1+2p 成立,因此通过随机选取参数
a,b 有较多的群可供选取。
选定
B 之后,我们随机
P0,在椭圆曲线群中计算
P=P0q≤B∏q⌊logqB⌋,数乘定义为多次进行加法。过程中如果出现
0 那么相当于寻找到了因子,我们再通过
gcd 提取即可。
一条曲线可能不足以完成分解,我们随机生成多条曲线即可。算法在椭圆曲线的阶因子均不超过
B 时完成,复杂度为
e(2+o(1))lnplnlnp ,渐进意义下不劣于二次筛法,并且在因子较小时效率更高。然而因为椭圆曲线群需要维护大量模意义下的运算,一般情况下跑不过二次筛法。/youl
3.科技
3.1 通用数域筛法
🫷够了