【学习笔记】快速 GCD 算法

目标:在 O ( V ) \mathcal O(V) O(V) 预处理的前提下,做到 O ( 1 ) \mathcal O(1) O(1) 求算 V V V 以内任意数对的 gcd ⁡ \gcd gcd

Lemma. 对于任意正整数 n n n,可以找到三个正整数 a , b , c    ( a ⩽ b ⩽ c ) a,b,c\;(a\leqslant b\leqslant c) a,b,c(abc) 使得 a b c = n abc=n abc=n,满足 a , b ⩽ n ∧ ( c ⩽ n ∨ c ∈ Prime ) a,b\leqslant\sqrt{n}\land(c\leqslant\sqrt{n}\vee c\in\text{Prime}) a,bn (cn cPrime)

Proof. 当 n n n 存在超过 n \sqrt n n 的质因子时,令 c c c 为该质因子即成立。因此只需证 n n n 只含小质因数的情况。

构造其分配方案:取 p p p n n n 最小质因数,由归纳法,将 n p n\over p pn 划分为 a , b , c    ( a ⩽ b ⩽ c ) a,b,c\;(a\leqslant b\leqslant c) a,b,c(abc) 。显然 a ⩽ n p 3 a\leqslant\sqrt[3]{n\over p} a3pn 。由归纳假设 b ⩽ n p b\leqslant\sqrt{n\over p} bpn ,且 c ⩽ n p ∨ c ∈ Prime c\leqslant\sqrt{n\over p}\vee c\in\text{Prime} cpn cPrime 。但是 n n n 的质因数都不超过 n \sqrt n n ,且 c ∣ n c\mid n cn,所以总是有 c ⩽ n c\leqslant\sqrt n cn 。对 p p p 的大小进行分类讨论:

  • p ⩽ n 4 p\leqslant\sqrt[4]{n} p4n ,则 a p ⩽ n p 3 ⋅ p = n p 2 3 ⩽ n ap\leqslant\sqrt[3]{n\over p}\cdot p=\sqrt[3]{np^2}\leqslant\sqrt{n} ap3pn p=3np2 n ,于是 a p , b , c ap,b,c ap,b,c 就是合法的划分。
  • 否则,若 a ⩾ p a\geqslant p ap n = p a b c ⩾ p 4 > n n=pabc\geqslant p^4>n n=pabcp4>n,矛盾,故 a < p a<p a<p 。又因 p p p 是最小质因数 ⇒ a = 1 \Rightarrow a=1 a=1 。显然最小质因子 p ⩽ n p\leqslant\sqrt{n} pn ,所以 p , b , c p,b,c p,b,c 就是合法的划分。

Q.E.D.

顺便给出了求解方法:线性筛的时候知道了 p p p,直接叠加到 n p n\over p pn 划分中的最小数上就行。

知道了这个之后呢?那么原来的 gcd ⁡ ( n , v ) \gcd(n,v) gcd(n,v) 可以变为 gcd ⁡ ( a b c , v ) \gcd(abc,v) gcd(abc,v) 。预处理 O ( n × n ) = O ( n ) \mathcal O(\sqrt{n}\times\sqrt{n})=\mathcal O(n) O(n ×n )=O(n) gcd ⁡ \gcd gcd 表,可以直接查询 gcd ⁡ ( a , v ) = gcd ⁡ ( a ,    v   m o d   a ) \gcd(a,v)=\gcd(a,\;v\bmod a) gcd(a,v)=gcd(a,vmoda),因为与质数求 gcd ⁡ \gcd gcd 是平凡的。

gcd ⁡ \gcd gcd 是质因子指数取 min ⁡ \min min,相当于两边同时除以 d d d 使得二者不再能同时除以任意一个数。所以每次 v v v a a a b b b gcd ⁡ \gcd gcd 后,直接将 v v v 除以这么多就可以了。具体可见代码。

所以这是 O ( V ) \mathcal O(V) O(V) 预处理之后 O ( 3 ) \mathcal O(3) O(3) 查询的方法。


上面的 Lemma \text{Lemma} Lemma 似乎很需要些猜测才能得到。不妨试试 HALF-GCD \textit{HALF-GCD} HALF-GCD 的方法:将每个数视为 x = 2 x=2 x=2 的关于 x x x 的多项式即可。有复杂度
T ( n ) = 2 T ( n 2 ) + O ( 1 ) \mathcal T(n)=2\mathcal T\left({n\over 2}\right)+\mathcal O(1) T(n)=2T(2n)+O(1)

其中 n n n 是多项式的长度。不难发现,若我们预处理 V α V^{\alpha} Vα 以内的数对的 gcd ⁡ \gcd gcd 其中 α \alpha α ( 0 , 1 ) (0,1) (0,1) 内常数,则递归层数是常数 log ⁡ 2 ( α − 1 ) \log_2(\alpha^{-1}) log2(α1) ,故这也是 O ( 1 ) \mathcal O(1) O(1) 的查询。

skip2004 \texttt{skip2004} skip2004 所说,处理 V 1 / 3 V^{1/3} V1/3 内的数对的 gcd ⁡ \gcd gcd 是跑得很快的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值