Orac and LCM

cf 641 A

证明

给定一个正整数序列 a={a1,a2,,an}a = \{a_1, a_2, \ldots, a_n\} (n2n \ge 2)。
定义多重集合 t={lcm(ai,aj)1i<jn}t = \{ \text{lcm}(a_i, a_j) \mid 1 \le i < j \le n \},即所有不同元素对的最小公倍数 (LCM) 的集合。
我们的目标是计算 g=gcd(t)g = \gcd(t),即集合 tt 中所有元素的最大公约数 (GCD)。

为了方便证明,我们定义:

  • gk=gcd({lcm(ak,ai)1in,ik})g_k = \gcd(\{ \text{lcm}(a_k, a_i) \mid 1 \le i \le n, i \ne k \}),即所有涉及 aka_k 的 LCM 对的 GCD。
  • dk=gcd({ai1in,ik})d_k = \gcd(\{ a_i \mid 1 \le i \le n, i \ne k \}),即除了 aka_k 外所有其他 aia_i 的 GCD。

证明 1:g=gcd(g1,g2,,gn)g = \gcd(g_1, g_2, \ldots, g_n)

我们需要证明 ggG=gcd(g1,g2,,gn)G = \gcd(g_1, g_2, \ldots, g_n) 相等。我们将通过证明 gGg \mid GGgG \mid g 来完成。

部分 1:证明 gGg \mid G

  1. 根据 g=gcd(t)g = \gcd(t) 的定义,gg 必须整除集合 tt 中的每一个元素。即 1i<jn\forall 1 \le i < j \le n, glcm(ai,aj)g \mid \text{lcm}(a_i, a_j)
  2. 考虑任意固定的 kk (1kn1 \le k \le n)。对于所有 iki \ne kgg 必须整除 lcm(ak,ai)\text{lcm}(a_k, a_i) (如果 i<ki < k,则由步骤 1 直接得到;如果 i>ki > k,也由步骤 1 直接得到)。
  3. 因为 gg 整除集合 {lcm(ak,ai)ik}\{ \text{lcm}(a_k, a_i) \mid i \ne k \} 中的每一个元素,所以根据 GCD 的性质,gg 必须整除这些元素的 GCD。即 ggcd({lcm(ak,ai)ik})g \mid \gcd(\{ \text{lcm}(a_k, a_i) \mid i \ne k \})
  4. 根据 gkg_k 的定义,这意味着 ggkg \mid g_k
  5. 由于 gg 整除 gkg_k 对于所有的 k=1,,nk = 1, \ldots, n 都成立,所以 gg 必须整除 g1,g2,,gng_1, g_2, \ldots, g_n 的最大公约数。
  6. 因此,ggcd(g1,g2,,gn)g \mid \gcd(g_1, g_2, \ldots, g_n),即 gGg \mid G

部分 2:证明 GgG \mid g

  1. G=gcd(g1,g2,,gn)G = \gcd(g_1, g_2, \ldots, g_n)。根据 GCD 的定义,GG 整除每一个 gkg_k
  2. 考虑任意 kk。我们知道 GgkG \mid g_kgk=gcd({lcm(ak,ai)ik})g_k = \gcd(\{ \text{lcm}(a_k, a_i) \mid i \ne k \})。这意味着 GG 必须整除集合 {lcm(ak,ai)ik}\{ \text{lcm}(a_k, a_i) \mid i \ne k \} 中的每一个元素。即 ik\forall i \ne k, Glcm(ak,ai)G \mid \text{lcm}(a_k, a_i)
  3. 现在考虑集合 tt 中的任意元素 lcm(ai,aj)\text{lcm}(a_i, a_j),其中 i<ji < j
  4. 根据步骤 2,因为 GgiG \mid g_i,所以 GG 整除所有涉及 aia_i 的 LCM 对,特别地,Glcm(ai,aj)G \mid \text{lcm}(a_i, a_j) (因为 jij \ne i)。
  5. 由于 GG 整除集合 tt 中的 每一个 元素 lcm(ai,aj)\text{lcm}(a_i, a_j),所以根据 GCD 的定义,GG 必须整除集合 tt 中所有元素的 GCD。
  6. 因此,Ggcd(t)G \mid \gcd(t),即 GgG \mid g

结论 1:
因为 gGg \mid GGgG \mid g,并且 g,Gg, G 都是正整数(GCD 总是正的),所以 g=Gg = G
即:gcd(t)=gcd(g1,g2,,gn)\gcd(t) = \gcd(g_1, g_2, \ldots, g_n)

证明 2:gk=lcm(ak,dk)g_k = \text{lcm}(a_k, d_k)

我们需要证明 gcd({lcm(ak,ai)ik})=lcm(ak,gcd({aiik}))\gcd(\{ \text{lcm}(a_k, a_i) \mid i \ne k \}) = \text{lcm}(a_k, \gcd(\{ a_i \mid i \ne k \}))

我们将使用 GCD 和 LCM 的一个重要的(类似分配律的)性质:
对于任意正整数 X,Y1,,YmX, Y_1, \ldots, Y_m,有:

gcd(lcm(X,Y1),lcm(X,Y2),,lcm(X,Ym))=lcm(X,gcd(Y1,Y2,,Ym))\gcd(\text{lcm}(X, Y_1), \text{lcm}(X, Y_2), \ldots, \text{lcm}(X, Y_m)) = \text{lcm}(X, \gcd(Y_1, Y_2, \ldots, Y_m))

证明该性质(使用素数幂分解):
令任意素数 pp。设 X=pαXX = p^{\alpha} \cdot X', Yj=pβjYjY_j = p^{\beta_j} \cdot Y'_j,其中 X,YjX', Y'_j 不含素因子 pp

  • 左侧 (LHS) 的 pp 的指数是:
    min(max(α,β1),max(α,β2),,max(α,βm))\min(\max(\alpha, \beta_1), \max(\alpha, \beta_2), \ldots, \max(\alpha, \beta_m))
  • 右侧 (RHS) 的 pp 的指数是:
    max(α,min(β1,β2,,βm))\max(\alpha, \min(\beta_1, \beta_2, \ldots, \beta_m))

我们需要证明 minj(max(α,βj))=max(α,minj(βj))\min_{j}(\max(\alpha, \beta_j)) = \max(\alpha, \min_{j}(\beta_j))
βmin=minj(βj)\beta_{\min} = \min_{j}(\beta_j)

  • 情况 1: 如果 αβmin\alpha \le \beta_{\min}
    • LHS: max(α,βj)α\max(\alpha, \beta_j) \ge \alphamax(α,βj)βjβmin\max(\alpha, \beta_j) \ge \beta_j \ge \beta_{\min}。因为 αβmin\alpha \le \beta_{\min},所以对于某个 jj' 使得 βj=βmin\beta_{j'} = \beta_{\min},我们有 max(α,βj)=βmin\max(\alpha, \beta_{j'}) = \beta_{\min}。对于其他的 βjβmin\beta_j \ge \beta_{\min},有 max(α,βj)βmin\max(\alpha, \beta_j) \ge \beta_{\min}。所以 minj(max(α,βj))=βmin\min_{j}(\max(\alpha, \beta_j)) = \beta_{\min}
    • RHS: max(α,minj(βj))=max(α,βmin)=βmin\max(\alpha, \min_{j}(\beta_j)) = \max(\alpha, \beta_{\min}) = \beta_{\min} (因为 αβmin\alpha \le \beta_{\min})。
    • 两侧相等。
  • 情况 2: 如果 α>βmin\alpha > \beta_{\min}
    • LHS: max(α,βj)\max(\alpha, \beta_j)。因为 α>βmin\alpha > \beta_{\min},所以对于某个 jj' 使得 βj=βmin\beta_{j'} = \beta_{\min},我们有 max(α,βj)=α\max(\alpha, \beta_{j'}) = \alpha。对于其他的 βjβmin\beta_j \ge \beta_{\min},如果 βjα\beta_j \ge \alpha,则 max(α,βj)=βjα\max(\alpha, \beta_j) = \beta_j \ge \alpha;如果 βj<α\beta_j < \alpha,则 max(α,βj)=α\max(\alpha, \beta_j) = \alpha。因此,所有 max(α,βj)\max(\alpha, \beta_j) 的值都 α\ge \alpha,且至少有一个等于 α\alpha。所以 minj(max(α,βj))=α\min_{j}(\max(\alpha, \beta_j)) = \alpha
    • RHS: max(α,minj(βj))=max(α,βmin)=α\max(\alpha, \min_{j}(\beta_j)) = \max(\alpha, \beta_{\min}) = \alpha (因为 α>βmin\alpha > \beta_{\min})。
    • 两侧相等。

因此,该性质对于任意素数 pp 的指数都成立,故性质本身成立。

应用该性质:
在我们的问题中,令 X=akX = a_k,令集合 {Y1,,Ym}\{Y_1, \ldots, Y_m\}{aiik}\{a_i \mid i \ne k\}
那么根据该性质:

gcd({lcm(ak,ai)ik})=lcm(ak,gcd({aiik}))\gcd(\{ \text{lcm}(a_k, a_i) \mid i \ne k \}) = \text{lcm}(a_k, \gcd(\{ a_i \mid i \ne k \}))

根据 gkg_kdkd_k 的定义,上式即为:

gk=lcm(ak,dk)g_k = \text{lcm}(a_k, d_k)

证明完毕。

最终结论

结合两个证明:

  1. 我们需要计算 g=gcd(t)g = \gcd(t)
  2. 我们证明了 g=gcd(g1,g2,,gn)g = \gcd(g_1, g_2, \ldots, g_n)
  3. 我们证明了 gk=lcm(ak,dk)g_k = \text{lcm}(a_k, d_k),其中 dk=gcd(aiik)d_k = \gcd(a_i | i \ne k)

因此,最终的计算方法是:

g=gcd(lcm(a1,d1),lcm(a2,d2),,lcm(an,dn))g = \gcd(\text{lcm}(a_1, d_1), \text{lcm}(a_2, d_2), \ldots, \text{lcm}(a_n, d_n))

其中 dkd_k 可以通过预计算前缀和后缀 GCD 来高效获得。

参考代码 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
vector<long long> prefix(n);
vector<long long> suffix(n);
prefix[0] = arr[0];
for(int i = 1; i < n; ++i) {
prefix[i] = std::gcd(prefix[i - 1], 1LL * arr[i]);
}
suffix[n - 1] = arr[n - 1];
for(int i = n - 2; i >= 0; --i) {
suffix[i] = std::gcd(suffix[i + 1], 1LL * arr[i]);
}

long long ans = 0;
for(int i = 0; i < n; ++i) {
long long k;
if(i == 0) {
k = suffix[1];
} else if(i == n - 1) {
k = prefix[n - 2];
} else {
k = std::gcd(prefix[i - 1] , suffix[i + 1]);
}

k = std::lcm(1LL * arr[i], k);
if(k != 0) {
ans = std::gcd(ans, k);
} else {
ans = k;
}
}

cout << ans << nl;

下面我们换一种思路来理解

usaco guide

先看代码 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
long long n , a , b;
input(n, a, b);

auto opt = [&]() {
long long t = std::gcd(a,b);
std::tie(a,b) = std::make_pair(t , a / t * b);
};

opt();
for(int i = 2; i < n; ++i) {
long long t;
input(t);
b = std::gcd(b, t);
opt();
}

cout << b << nl;


问题分析:对中最小公倍数的最大公约数

问题描述

给定一个包含 nn 个正整数的序列 a={a1,a2,,an}a = \{a_1, a_2, \dots, a_n\},其中 n2n \ge 2
定义一个多重集 t={lcm(ai,aj)1i<jn}t = \{ \text{lcm}(a_i, a_j) \mid 1 \le i < j \le n \}
目标是计算 G=gcd(t)G = \gcd(t)

换句话说,我们需要计算:

G=gcd({lcm(ai,aj)1i<jn})G = \gcd \left( \{ \text{lcm}(a_i, a_j) \mid 1 \le i < j \le n \} \right)

算法概述(迭代方法)

维护两个变量,我们称之为 gl(对应代码中的 ab)。

在处理完前 kk 个元素 {a1,,ak}\{a_1, \dots, a_k\} 后(其中 k2k \ge 2),这两个变量存储以下值:

  • g = Gk=gcd(a1,a2,,ak)G_k = \gcd(a_1, a_2, \dots, a_k)
  • l = Tk=gcd({lcm(ai,aj)1i<jk})T_k = \gcd(\{ \text{lcm}(a_i, a_j) \mid 1 \le i < j \le k \})

算法流程如下:

  1. 初始化(使用 a1,a2a_1, a_2):计算 G2=gcd(a1,a2)G_2 = \gcd(a_1, a_2)T2=lcm(a1,a2)T_2 = \text{lcm}(a_1, a_2)。将它们存入 gl
  2. 循环(从 k=3k = 3nn):读取 aka_k。使用前一步的 Gk1G_{k-1}Tk1T_{k-1} 和新元素 aka_k 来更新 gGkG_klTkT_k
  3. 结果:处理完 ana_n 后,存储在 l 中的值即为最终答案 TnT_n

正确性证明

我们使用数学归纳法来证明该算法在每一步 kk 都能在变量 l 中正确计算出 TkT_k

定义

  • Gk=gcd(a1,,ak)G_k = \gcd(a_1, \dots, a_k)
  • Tk=gcd({lcm(ai,aj)1i<jk})T_k = \gcd(\{ \text{lcm}(a_i, a_j) \mid 1 \le i < j \le k \}) (我们在第 kk 步的目标值)
  • Sk=gcd({lcm(ak,ai)1i<k})S_k = \gcd(\{ \text{lcm}(a_k, a_i) \mid 1 \le i < k \}) (涉及新元素 aka_k 的所有配对的 lcm 的 gcd)

TkT_k 的递推关系

满足 1i<jk1 \le i < j \le k 的数对 (i,j)(i, j) 可以分为两组:

  1. j<kj < k 的数对:{(i,j)1i<jk1}\{ (i, j) \mid 1 \le i < j \le k-1 \}
  2. j=kj = k 的数对:{(i,k)1i<k}\{ (i, k) \mid 1 \le i < k \}

根据 gcd\gcd 的性质 gcd(AB)=gcd(gcd(A),gcd(B))\gcd(A \cup B) = \gcd(\gcd(A), \gcd(B)),我们得到:

Tk=gcd(gcd({lcm(ai,aj)1i<jk1})Tk1,gcd({lcm(ak,ai)1i<k})Sk)T_k = \gcd(\underbrace{\gcd(\{ \text{lcm}(a_i, a_j) \mid 1 \le i < j \le k-1 \})}_{T_{k-1}}, \underbrace{\gcd(\{ \text{lcm}(a_k, a_i) \mid 1 \le i < k \})}_{S_k})

Tk=gcd(Tk1,Sk)T_k = \gcd(T_{k-1}, S_k)

关键恒等式

我们可以证明(通过素数分解和指数上的 min/max 运算):

Sk=gcd({lcm(ak,ai)1i<k})=lcm(ak,gcd({ai1i<k}))S_k = \gcd(\{ \text{lcm}(a_k, a_i) \mid 1 \le i < k \}) = \text{lcm}(a_k, \gcd(\{ a_i \mid 1 \le i < k \}))

Sk=lcm(ak,Gk1)S_k = \text{lcm}(a_k, G_{k-1})

组合递推公式

将上述恒等式代入 TkT_k 的递推关系:

Tk=gcd(Tk1,lcm(ak,Gk1))T_k = \gcd(T_{k-1}, \text{lcm}(a_k, G_{k-1}))

这就是算法在第 kk 步需要为变量 l 计算出的目标值。

分析代码的更新步骤

gk1\texttt{g}_{k-1}lk1\texttt{l}_{k-1} 为处理 aka_k 之前的值。根据归纳假设,gk1=Gk1\texttt{g}_{k-1} = G_{k-1}lk1=Tk1\texttt{l}_{k-1} = T_{k-1}。代码执行:

  1. 读取 t=akt = a_k
  2. 计算中间值 ltemp=gcd(lk1,t)=gcd(Tk1,ak)\texttt{l}_{\text{temp}} = \gcd(\texttt{l}_{k-1}, t) = \gcd(T_{k-1}, a_k)
  3. 调用 opt(gk1,ltemp)\texttt{opt}(\texttt{g}_{k-1}, \texttt{l}_{\text{temp}})。设新值为 gk,lk\texttt{g}_k, \texttt{l}_k
    • gk=gcd(gk1,ltemp)=gcd(Gk1,gcd(Tk1,ak))\texttt{g}_k = \gcd(\texttt{g}_{k-1}, \texttt{l}_{\text{temp}}) = \gcd(G_{k-1}, \gcd(T_{k-1}, a_k))
    • lk=lcm(gk1,ltemp)=lcm(Gk1,gcd(Tk1,ak))\texttt{l}_k = \text{lcm}(\texttt{g}_{k-1}, \texttt{l}_{\text{temp}}) = \text{lcm}(G_{k-1}, \gcd(T_{k-1}, a_k))

我们需要验证:

  1. 验证 gk=Gk\texttt{g}_k = G_k
    我们需要证明 gcd(Gk1,gcd(Tk1,ak))=gcd(Gk1,ak)\gcd(G_{k-1}, \gcd(T_{k-1}, a_k)) = \gcd(G_{k-1}, a_k)
    这个等式成立,因为 Gk1aiG_{k-1} | a_i (对于 i<ki < k),这意味着 Gk1lcm(ai,aj)G_{k-1} | \text{lcm}(a_i, a_j) (对于 i<j<ki < j < k),因此 Gk1Tk1G_{k-1} | T_{k-1}。令 vp()v_p(\cdot) 表示素数 pp 的指数。则 vp(Gk1)vp(Tk1)v_p(G_{k-1}) \le v_p(T_{k-1})
    vp()=min(vp(Gk1),min(vp(Tk1),vp(ak)))=min(vp(Gk1),vp(ak))v_p(\text{左}) = \min(v_p(G_{k-1}), \min(v_p(T_{k-1}), v_p(a_k))) = \min(v_p(G_{k-1}), v_p(a_k)) (因为 vp(Gk1)vp(Tk1)v_p(G_{k-1}) \le v_p(T_{k-1}))。
    vp()=min(vp(Gk1),vp(ak))v_p(\text{右}) = \min(v_p(G_{k-1}), v_p(a_k))
    由于所有素数 pp 的指数都匹配,等式成立。因此 gk=Gk\texttt{g}_k = G_k

  2. 验证 lk=Tk\texttt{l}_k = T_k
    我们需要证明 lcm(Gk1,gcd(Tk1,ak))=gcd(Tk1,lcm(ak,Gk1))\text{lcm}(G_{k-1}, \gcd(T_{k-1}, a_k)) = \gcd(T_{k-1}, \text{lcm}(a_k, G_{k-1}))
    g=vp(Gk1),t=vp(Tk1),v=vp(ak)g=v_p(G_{k-1}), t=v_p(T_{k-1}), v=v_p(a_k)。我们需要证明 max(g,min(t,v))=min(t,max(v,g))\max(g, \min(t, v)) = \min(t, \max(v, g))
    我们已知 gtg \le t。当 gtg \le t 时,这个关于非负整数的恒等式成立。它是整数在整除关系构成的格(Lattice)上的分配律的一种形式(其中 lcm \leftrightarrow max,gcd \leftrightarrow min 对应于指数运算)。
    由于所有素数 pp 的指数都匹配,等式成立。因此 lk=Tk\texttt{l}_k = T_k

基础情况

对于 k=2k=2,代码计算 g=gcd(a1,a2)=G2\texttt{g} = \gcd(a_1, a_2) = G_2l=lcm(a1,a2)=T2\texttt{l} = \text{lcm}(a_1, a_2) = T_2。基础情况成立。

结论

通过数学归纳法,我们证明了在处理完 aka_k 后,变量 l 正确地存储了值 TkT_k。因此,在处理完 ana_n 后,l 存储了 TnT_n,即为题目所求的答案 GG


Orac and LCM
http://example.com/2025/04/21/Orac-and-LCM/
Author
Anfsity
Posted on
April 21, 2025
Licensed under