目标:在 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(a⩽b⩽c) 使得 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,b⩽n∧(c⩽n∨c∈Prime) 。
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(a⩽b⩽c) 。显然 a ⩽ n p 3 a\leqslant\sqrt[3]{n\over p} a⩽3pn 。由归纳假设 b ⩽ n p b\leqslant\sqrt{n\over p} b⩽pn,且 c ⩽ n p ∨ c ∈ Prime c\leqslant\sqrt{n\over p}\vee c\in\text{Prime} c⩽pn∨c∈Prime 。但是 n n n 的质因数都不超过 n \sqrt n n,且 c ∣ n c\mid n c∣n,所以总是有 c ⩽ n c\leqslant\sqrt n c⩽n 。对 p p p 的大小进行分类讨论:
- 若 p ⩽ n 4 p\leqslant\sqrt[4]{n} p⩽4n,则 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} ap⩽3pn⋅p=3np2⩽n,于是 a p , b , c ap,b,c ap,b,c 就是合法的划分。
- 否则,若 a ⩾ p a\geqslant p a⩾p 则 n = p a b c ⩾ p 4 > n n=pabc\geqslant p^4>n n=pabc⩾p4>n,矛盾,故 a < p a<p a<p 。又因 p p p 是最小质因数 ⇒ a = 1 \Rightarrow a=1 ⇒a=1 。显然最小质因子 p ⩽ n p\leqslant\sqrt{n} p⩽n,所以 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 是跑得很快的。