莫比乌斯反演 前置知识:数论分块 、狄利克雷卷积 
莫比乌斯反演是数论中的重要内容.对于一些函数 𝑓 ( 𝑛 ) f ( n ) 𝑔 ( 𝑛 ) g ( n ) 𝑓 ( 𝑛 ) f ( n ) 
莫比乌斯函数 莫比乌斯函数(Möbius 函数)定义为
𝜇 ( 𝑛 ) = ⎧ { { ⎨ { { ⎩ 1 , 𝑛 = 1 , 0 , 𝑛   i s   d i v i s i b l e   b y   a   s q u a r e   > 1 , ( − 1 ) 𝑘 , 𝑛   i s   t h e   p r o d u c t   o f   𝑘   d i s t i n c t   p r i m e s . μ ( n ) = { 1 , n = 1 , 0 , n  is divisible by a square  > 1 , ( − 1 ) k , n  is the product of  k  distinct primes . 具体地,假设正整数 𝑛 n 𝑛   = ∏ 𝑘 𝑖 = 1 𝑝 𝑒 𝑖 𝑖 n = ∏ i = 1 k p i e i 𝑝 𝑖 p i 𝑒 𝑖 e i 
𝜇 ( 1 )   = 1 μ ( 1 ) = 1 当存在 𝑖 i 𝑒 𝑖   > 1 e i > 1 𝜇 ( 𝑛 )   = 0 μ ( n ) = 0  否则,对于所有 𝑖 i 𝑒 𝑖   = 1 e i = 1 𝜇 ( 𝑛 )   = (   − 1 ) 𝑘 μ ( n ) = ( − 1 ) k 𝑘 k  性质 根据定义容易验证,莫比乌斯函数 𝜇 ( 𝑛 ) μ ( n ) 
性质  对于正整数 𝑛 n 
 ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑑 ) = [ 𝑛 = 1 ] = { 1 , 𝑛 = 1 , 0 , 𝑛 ≠ 1 . ∑ d ∣ n μ ( d ) = [ n = 1 ] = { 1 , n = 1 , 0 , n ≠ 1. 其中 [   ⋅ ] [ ⋅ ] 
证明  令 𝑛   = ∏ 𝑘 𝑖 = 1 𝑝 𝑒 𝑖 𝑖 n = ∏ i = 1 k p i e i 𝑛 ′   = ∏ 𝑘 𝑖 = 1 𝑝 𝑖 n ′ = ∏ i = 1 k p i 二项式定理 ,有
 ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑑 ) = ∑ 𝑑 ∣ 𝑛 ′ 𝜇 ( 𝑑 ) = 𝑘 ∑ 𝑖 = 0 ( 𝑘 𝑖 ) ( − 1 ) 𝑖 = ( 1 + ( − 1 ) ) 𝑘 = [ 𝑘 = 0 ] = [ 𝑛 = 1 ] . ∑ d ∣ n μ ( d ) = ∑ d ∣ n ′ μ ( d ) = ∑ i = 0 k ( k i ) ( − 1 ) i = ( 1 + ( − 1 ) ) k = [ k = 0 ] = [ n = 1 ] . 利用 Dirichlet 卷积,该表达式可以写作 𝜀   = 1   ∗ 𝜇 ε = 1 ∗ μ 1 1 
这一性质有一个很常见的应用:
[ 𝑖 ⟂ 𝑗 ] = [ g c d ( 𝑖 , 𝑗 ) = 1 ] = ∑ 𝑑 ∣ g c d ( 𝑖 , 𝑗 ) 𝜇 ( 𝑑 ) = ∑ 𝑑 [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑗 ] 𝜇 ( 𝑑 ) . [ i ⟂ j ] = [ gcd ( i , j ) = 1 ] = ∑ d ∣ gcd ( i , j ) μ ( d ) = ∑ d [ d ∣ i ] [ d ∣ j ] μ ( d ) . 它将互素的条件转化为关于莫比乌斯函数的求和式,方便进一步推导.
求法 如果需要对单个 𝑛 n 𝜇 ( 𝑛 ) μ ( n ) 质因数分解 .例如,在 𝑛 n 𝑂 ( √ 𝑛 ) O ( n ) 𝜇 ( 𝑛 ) μ ( n ) 
参考实现  如果需要对前 𝑛 n 𝜇 ( 𝑛 ) μ ( n ) 线性筛  在 𝑂 ( 𝑛 ) O ( n ) 
参考实现  莫比乌斯反演 莫比乌斯函数最重要的应用就是莫比乌斯反演.
莫比乌斯反演  设 𝑓 ( 𝑛 ) , 𝑔 ( 𝑛 ) f ( n ) , g ( n ) 
 𝑓 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝑔 ( 𝑑 ) ⟺ 𝑔 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) 𝑓 ( 𝑑 ) . f ( n ) = ∑ d ∣ n g ( d ) ⟺ g ( n ) = ∑ d ∣ n μ ( n d ) f ( d ) . 证明一  直接验证,有:
 ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) 𝑓 ( 𝑑 ) = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) ∑ 𝑘 ∣ 𝑑 𝑔 ( 𝑘 ) = ∑ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ∑ 𝑑 [ 𝑘 ∣ 𝑑 ∣ 𝑛 ] 𝜇 ( 𝑛 𝑑 ) = ∑ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ∑ 𝑑 ∣ 𝑛 [ 𝑛 𝑑 ∣ 𝑛 𝑘 ] 𝜇 ( 𝑛 𝑑 ) = ∑ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) [ 𝑛 𝑘 = 1 ] = 𝑔 ( 𝑛 ) . ∑ d ∣ n μ ( n d ) f ( d ) = ∑ d ∣ n μ ( n d ) ∑ k ∣ d g ( k ) = ∑ k ∣ n g ( k ) ∑ d [ k ∣ d ∣ n ] μ ( n d ) = ∑ k ∣ n g ( k ) ∑ d ∣ n [ n d ∣ n k ] μ ( n d ) = ∑ k ∣ n g ( k ) [ n k = 1 ] = g ( n ) . 式子变形的关键在于交换求和次序,并注意到 𝑘   ∣ 𝑑   ∣ 𝑛 k ∣ d ∣ n 𝑛 𝑑   ∣ 𝑛 𝑘 n d ∣ n k 𝑛 𝑘 n k 𝑛 𝑑 n d [ 𝑛 𝑘 = 1 ] [ n k = 1 ] 𝑛   = 𝑘 n = k 0 0 𝑔 ( 𝑛 ) g ( n ) 
证明二  利用 Dirichlet 卷积,命题等价于
 𝑓 = 1 ∗ 𝑔 ⟺ 𝑔 = 𝜇 ∗ 𝑓 . f = 1 ∗ g ⟺ g = μ ∗ f . 利用 1   ∗ 𝜇   = 𝜀 1 ∗ μ = ε 𝜇 μ 
 𝑓 ∗ 𝜇 = ( 1 ∗ 𝑔 ) ∗ 𝜇 = ( 1 ∗ 𝜇 ) ∗ 𝑔 = 𝜀 ∗ 𝑔 = 𝑔 . f ∗ μ = ( 1 ∗ g ) ∗ μ = ( 1 ∗ μ ) ∗ g = ε ∗ g = g . 在涉及各种整除关系的数论函数求和中,莫比乌斯反演是有力的变形工具.
例子  欧拉函数  𝜑 ( 𝑛 ) φ ( n ) 𝑛   = ∑ 𝑑 ∣ 𝑛 𝜑 ( 𝑑 ) n = ∑ d ∣ n φ ( d ) i d   = 1   ∗ 𝜑 id = 1 ∗ φ 𝜑   = 𝜇   ∗ i d φ = μ ∗ id 
 𝜑 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝑑 𝜇 ( 𝑛 𝑑 ) . φ ( n ) = ∑ d ∣ n d μ ( n d ) . 除数函数 𝜎 𝑘 ( 𝑛 )   = ∑ 𝑑 ∣ 𝑛 𝑑 𝑘 σ k ( n ) = ∑ d ∣ n d k 𝜎 𝑘   = 1   ∗ i d 𝑘 σ k = 1 ∗ id k i d 𝑘   = 𝜇   ∗ 𝜎 𝑘 id k = μ ∗ σ k 
 𝑛 𝑘 = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) 𝜎 𝑘 ( 𝑑 ) . n k = ∑ d ∣ n μ ( n d ) σ k ( d ) . 互异素因子数目函数 𝜔 ( 𝑛 )   = ∑ 𝑑 ∣ 𝑛 [ 𝑑   ∈ 𝐏 ] ω ( n ) = ∑ d ∣ n [ d ∈ P ] 𝜔   = 1   ∗ 𝟏 𝐏 ω = 1 ∗ 1 P 𝟏 𝐏 1 P 𝐏 P 𝟏 𝐏   = 𝜇   ∗ 𝜔 1 P = μ ∗ ω 
 [ 𝑛 ∈ 𝐏 ] = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) 𝜔 ( 𝑑 ) . [ n ∈ P ] = ∑ d ∣ n μ ( n d ) ω ( d ) . 考察满足 l o g  𝑛   = ∑ 𝑑 ∣ 𝑛 Λ ( 𝑑 ) log  n = ∑ d ∣ n Λ ( d ) Λ ( 𝑛 ) Λ ( n ) 
 Λ ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) l o g  𝑑 = { l o g  𝑝 , 𝑛 = 𝑝 𝑒 ,   𝑝 ∈ 𝐏 ,   𝑒 ∈ 𝐍 + , 0 , o t h e r w i s e . Λ ( n ) = ∑ d ∣ n μ ( n d ) log  d = { log  p , n = p e ,   p ∈ P ,   e ∈ N + , 0 , otherwise . 附:Λ ( 𝑛 ) Λ ( n )   对于素数幂 𝑛   = 𝑝 𝑒   ( 𝑒   ∈ 𝐍 + ) n = p e   ( e ∈ N + ) 
 Λ ( 𝑛 ) = 𝑒 ∑ 𝑖 = 0 𝜇 ( 𝑝 𝑒 − 𝑖 ) l o g  𝑝 𝑖 = l o g  𝑝 𝑒 − l o g  𝑝 𝑒 − 1 = l o g  𝑝 . Λ ( n ) = ∑ i = 0 e μ ( p e − i ) log  p i = log  p e − log  p e − 1 = log  p . 对于 𝑛   = 1 n = 1 Λ ( 𝑛 )   = l o g  1   = 0 Λ ( n ) = log  1 = 0 𝑛 n 
 Λ ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑑 ) ( l o g  𝑛 − l o g  𝑑 ) = ⎛ ⎜ ⎜ ⎝ ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑑 ) ⎞ ⎟ ⎟ ⎠ l o g  𝑛 − ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑑 ) l o g  𝑑 . Λ ( n ) = ∑ d ∣ n μ ( d ) ( log  n − log  d ) = ( ∑ d ∣ n μ ( d ) ) log  n − ∑ d ∣ n μ ( d ) log  d . 根据莫比乌斯函数的性质,l o g  𝑛 log  n [ 𝑛   = 1 ]   = 0 [ n = 1 ] = 0 𝑑 d 𝑝   ∣ 𝑛 p ∣ n l o g  𝑝 log  p 
 − ∑ 𝑝 ∣ 𝑑 ∣ 𝑛 𝜇 ( 𝑑 ) = ∑ ( 𝑑 / 𝑝 ) ∣ ( 𝑛 / 𝑝 ) 𝜇 ( 𝑑 𝑝 ) = [ 𝑛 𝑝 = 1 ] = 0 . − ∑ p ∣ d ∣ n μ ( d ) = ∑ ( d / p ) ∣ ( n / p ) μ ( d p ) = [ n p = 1 ] = 0. 由此,对于不止一个素因子的合数 𝑛 n Λ ( 𝑛 )   = 0 Λ ( n ) = 0 
拓展形式 除了上述基本形式外,莫比乌斯反演还有一些常见的拓展形式.首先,可以考虑它的倍数和形式.
拓展一  设 𝑓 ( 𝑛 ) , 𝑔 ( 𝑛 ) f ( n ) , g ( n ) 
 𝑓 ( 𝑛 ) = ∑ 𝑛 ∣ 𝑑 𝑔 ( 𝑑 ) ⟺ 𝑔 ( 𝑛 ) = ∑ 𝑛 ∣ 𝑑 𝜇 ( 𝑑 𝑛 ) 𝑓 ( 𝑑 ) . f ( n ) = ∑ n ∣ d g ( d ) ⟺ g ( n ) = ∑ n ∣ d μ ( d n ) f ( d ) . 证明  直接验证,有:
 ∑ 𝑛 ∣ 𝑑 𝜇 ( 𝑑 𝑛 ) 𝑓 ( 𝑑 ) = ∑ 𝑛 ∣ 𝑑 𝜇 ( 𝑑 𝑛 ) ∑ 𝑑 ∣ 𝑘 𝑔 ( 𝑘 ) = ∑ 𝑛 ∣ 𝑘 𝑔 ( 𝑘 ) ∑ 𝑑 [ 𝑛 ∣ 𝑑 ∣ 𝑘 ] 𝜇 ( 𝑑 𝑛 ) = ∑ 𝑛 ∣ 𝑘 𝑔 ( 𝑘 ) ∑ 𝑛 ∣ 𝑑 [ 𝑑 𝑛 ∣ 𝑘 𝑛 ] 𝜇 ( 𝑑 𝑛 ) = ∑ 𝑛 ∣ 𝑘 𝑔 ( 𝑘 ) [ 𝑘 𝑛 = 1 ] = 𝑔 ( 𝑛 ) . ∑ n ∣ d μ ( d n ) f ( d ) = ∑ n ∣ d μ ( d n ) ∑ d ∣ k g ( k ) = ∑ n ∣ k g ( k ) ∑ d [ n ∣ d ∣ k ] μ ( d n ) = ∑ n ∣ k g ( k ) ∑ n ∣ d [ d n ∣ k n ] μ ( d n ) = ∑ n ∣ k g ( k ) [ k n = 1 ] = g ( n ) . 这和基本形式的推导完全对偶.
其次,莫比乌斯反演并不仅限于加法,它实际上对于任何 Abel 群  中的运算都成立.例如,它有如下的乘法形式:
拓展二  设 𝑓 ( 𝑛 ) , 𝑔 ( 𝑛 ) f ( n ) , g ( n ) 
 𝑓 ( 𝑛 ) = ∏ 𝑑 ∣ 𝑛 𝑔 ( 𝑑 ) ⟺ 𝑔 ( 𝑛 ) = ∏ 𝑑 ∣ 𝑛 𝑓 ( 𝑑 ) 𝜇 ( 𝑛 / 𝑑 ) . f ( n ) = ∏ d ∣ n g ( d ) ⟺ g ( n ) = ∏ d ∣ n f ( d ) μ ( n / d ) . 证明  直接验证,有:
 ∏ 𝑑 ∣ 𝑛 𝑓 ( 𝑑 ) 𝜇 ( 𝑛 / 𝑑 ) = ∏ 𝑑 ∣ 𝑛 ⎛ ⎜ ⎜ ⎝ ∏ 𝑘 ∣ 𝑑 𝑔 ( 𝑘 ) ⎞ ⎟ ⎟ ⎠ 𝜇 ( 𝑛 / 𝑑 ) = ∏ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ↑ ( ∑ 𝑑 [ 𝑘 ∣ 𝑑 ∣ 𝑛 ] 𝜇 ( 𝑛 𝑑 ) ) = ∏ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ↑ ⎛ ⎜ ⎜ ⎝ ∑ 𝑑 ∣ 𝑛 [ 𝑛 𝑑 ∣ 𝑛 𝑘 ] 𝜇 ( 𝑛 𝑑 ) ⎞ ⎟ ⎟ ⎠ = ∏ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ↑ [ 𝑛 𝑘 = 1 ] = 𝑔 ( 𝑛 ) . ∏ d ∣ n f ( d ) μ ( n / d ) = ∏ d ∣ n ( ∏ k ∣ d g ( k ) ) μ ( n / d ) = ∏ k ∣ n g ( k ) ↑ ( ∑ d [ k ∣ d ∣ n ] μ ( n d ) ) = ∏ k ∣ n g ( k ) ↑ ( ∑ d ∣ n [ n d ∣ n k ] μ ( n d ) ) = ∏ k ∣ n g ( k ) ↑ [ n k = 1 ] = g ( n ) . 其中,𝑎   ↑ 𝑏   = 𝑎 𝑏 a ↑ b = a b 
从 Dirichlet 卷积的角度看,莫比乌斯反演只是利用了「莫比乌斯函数是常值函数的 Dirichlet 逆」这一点.容易想象,类似莫比乌斯反演的关系对于一般的 Dirichlet 逆  同样成立.
拓展三  设 𝑓 ( 𝑛 ) , 𝑔 ( 𝑛 ) , 𝛼 ( 𝑛 ) f ( n ) , g ( n ) , α ( n ) 𝛼 − 1 ( 𝑛 ) α − 1 ( n ) 𝛼 ( 𝑛 ) α ( n ) 
 [ 𝑛 = 1 ] = ∑ 𝑑 ∣ 𝑛 𝛼 ( 𝑛 𝑑 ) 𝛼 − 1 ( 𝑑 ) . [ n = 1 ] = ∑ d ∣ n α ( n d ) α − 1 ( d ) . 那么,有
 𝑓 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝛼 ( 𝑛 𝑑 ) 𝑔 ( 𝑑 ) ⟺ 𝑔 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝛼 − 1 ( 𝑛 𝑑 ) 𝑓 ( 𝑑 ) . f ( n ) = ∑ d ∣ n α ( n d ) g ( d ) ⟺ g ( n ) = ∑ d ∣ n α − 1 ( n d ) f ( d ) . 证明  直接验证,有:
 ∑ 𝑑 ∣ 𝑛 𝛼 − 1 ( 𝑛 𝑑 ) 𝑓 ( 𝑑 ) = ∑ 𝑑 ∣ 𝑛 𝛼 − 1 ( 𝑛 𝑑 ) ∑ 𝑘 ∣ 𝑑 𝛼 ( 𝑑 𝑘 ) 𝑔 ( 𝑘 ) = ∑ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ∑ 𝑑 [ 𝑘 ∣ 𝑑 ∣ 𝑛 ] 𝛼 ( 𝑑 𝑘 ) 𝛼 − 1 ( 𝑛 𝑑 ) = ∑ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) ∑ 𝑑 ∣ 𝑛 [ 𝑛 𝑑 ∣ 𝑛 𝑘 ] 𝛼 ( 𝑑 𝑘 ) 𝛼 − 1 ( 𝑛 / 𝑘 𝑑 / 𝑘 ) = ∑ 𝑘 ∣ 𝑛 𝑔 ( 𝑘 ) [ 𝑛 𝑘 = 1 ] = 𝑔 ( 𝑛 ) . ∑ d ∣ n α − 1 ( n d ) f ( d ) = ∑ d ∣ n α − 1 ( n d ) ∑ k ∣ d α ( d k ) g ( k ) = ∑ k ∣ n g ( k ) ∑ d [ k ∣ d ∣ n ] α ( d k ) α − 1 ( n d ) = ∑ k ∣ n g ( k ) ∑ d ∣ n [ n d ∣ n k ] α ( d k ) α − 1 ( n / k d / k ) = ∑ k ∣ n g ( k ) [ n k = 1 ] = g ( n ) . 和基本形式的证明相比较,只需要将倒数第二个等号替换成 Dirichlet 逆的定义式.
推论  设 𝑓 ( 𝑛 ) , 𝑔 ( 𝑛 ) f ( n ) , g ( n ) 𝑡 ( 𝑛 ) t ( n ) 
 𝑓 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝑡 ( 𝑛 𝑑 ) 𝑔 ( 𝑑 ) ⟺ 𝑔 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) 𝑡 ( 𝑛 𝑑 ) 𝑓 ( 𝑑 ) . f ( n ) = ∑ d ∣ n t ( n d ) g ( d ) ⟺ g ( n ) = ∑ d ∣ n μ ( n d ) t ( n d ) f ( d ) . 证明  由 Dirichlet 卷积的 性质  可知,对于完全积性函数 𝑡 ( 𝑛 ) t ( n ) 𝜇 ( 𝑛 ) 𝑡 ( 𝑛 ) μ ( n ) t ( n ) 
最后,莫比乌斯反演还可以推广到 [ 1 ,   + ∞ ) [ 1 , + ∞ ) 
拓展四  设 𝐹 ( 𝑥 ) F ( x ) 𝐺 ( 𝑥 ) G ( x ) [ 1 ,   + ∞ ) [ 1 , + ∞ ) 
 𝐹 ( 𝑥 ) = ⌊ 𝑥 ⌋ ∑ 𝑛 = 1 𝐺 ( 𝑥 𝑛 ) ⟺ 𝐺 ( 𝑥 ) = ⌊ 𝑥 ⌋ ∑ 𝑛 = 1 𝜇 ( 𝑛 ) 𝐹 ( 𝑥 𝑛 ) . F ( x ) = ∑ n = 1 ⌊ x ⌋ G ( x n ) ⟺ G ( x ) = ∑ n = 1 ⌊ x ⌋ μ ( n ) F ( x n ) . 证明  不妨对 𝐹 F 𝐺 G 𝑥   < 1 x < 1 𝐹 ( 𝑥 )   = 𝐺 ( 𝑥 )   = 0 F ( x ) = G ( x ) = 0 
 𝐹 ( 𝑥 ) = ∑ 𝑛 𝐺 ( 𝑥 𝑛 ) ⟺ 𝐺 ( 𝑥 ) = ∑ 𝑛 𝜇 ( 𝑛 ) 𝐹 ( 𝑥 𝑛 ) . F ( x ) = ∑ n G ( x n ) ⟺ G ( x ) = ∑ n μ ( n ) F ( x n ) . 这些求和式都是对 𝑛   ∈ 𝐍 + n ∈ N + 
 直接验证,有:
 ∑ 𝑛 𝜇 ( 𝑛 ) 𝐹 ( 𝑥 𝑛 ) = ∑ 𝑛 𝜇 ( 𝑛 ) ∑ 𝑑 𝐺 ( 𝑥 / 𝑛 𝑑 ) = ∑ 𝑘 𝐺 ( 𝑥 𝑘 ) ∑ 𝑛 ∣ 𝑘 𝜇 ( 𝑛 ) = ∑ 𝑘 𝐺 ( 𝑥 𝑘 ) [ 𝑘 = 1 ] = 𝐺 ( 𝑥 ) . ∑ n μ ( n ) F ( x n ) = ∑ n μ ( n ) ∑ d G ( x / n d ) = ∑ k G ( x k ) ∑ n ∣ k μ ( n ) = ∑ k G ( x k ) [ k = 1 ] = G ( x ) . 其中,为得到第二个等号,需要令 𝑘   = 𝑛 𝑑 k = n d 
推论  设 𝑓 ( 𝑛 ) , 𝑔 ( 𝑛 ) f ( n ) , g ( n ) 
 𝑓 ( 𝑛 ) = 𝑛 ∑ 𝑘 = 1 𝑔 ( ⌊ 𝑛 𝑘 ⌋ ) ⟺ 𝑔 ( 𝑛 ) = 𝑛 ∑ 𝑘 = 1 𝜇 ( 𝑘 ) 𝑓 ( ⌊ 𝑛 𝑘 ⌋ ) . f ( n ) = ∑ k = 1 n g ( ⌊ n k ⌋ ) ⟺ g ( n ) = ∑ k = 1 n μ ( k ) f ( ⌊ n k ⌋ ) . 证明  只需要取 𝐹 ( 𝑥 )   = 𝑓 ( ⌊ 𝑥 ⌋ ) F ( x ) = f ( ⌊ x ⌋ ) 𝐺 ( 𝑥 )   = 𝑔 ( ⌊ 𝑥 ⌋ ) G ( x ) = g ( ⌊ x ⌋ ) 
这些拓展形式之间可以互相组合,进而得到更为复杂的反演关系.
Dirichlet 前缀和 前置知识:前缀和与差分 
考虑基本形式的莫比乌斯反演关系:
𝑓 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝑔 ( 𝑑 ) ⟺ 𝑔 ( 𝑛 ) = ∑ 𝑑 ∣ 𝑛 𝜇 ( 𝑛 𝑑 ) 𝑓 ( 𝑑 ) . f ( n ) = ∑ d ∣ n g ( d ) ⟺ g ( n ) = ∑ d ∣ n μ ( n d ) f ( d ) . 左侧等式中,𝑓 ( 𝑛 ) f ( n ) 𝑛 n 𝑔 ( 𝑛 ) g ( n ) 𝑎   ∣ 𝑏 a ∣ b 𝑎 a 𝑏 b 𝑓 ( 𝑛 ) f ( n ) 𝑔 ( 𝑛 ) g ( n ) { 𝑔 ( 𝑘 ) } 𝑛 𝑘 = 1 { g ( k ) } k = 1 n { 𝑓 ( 𝑘 ) } 𝑛 𝑘 = 1 { f ( k ) } k = 1 n Dirichlet 前缀和 ,相应的逆过程则称为 Dirichlet 差分.这些方法大多出现在需要预处理某个数论函数在前 𝑁 N 
接下来,讨论 Dirichlet 前缀和的计算.如果将每一个素数都看作一个维度,这就是一种高维前缀和.回忆高维前缀和的 逐维前缀和算法 :逐个遍历所有的维度,并将每个位置的值都累加到该位置在该维度上的后继位置.对于数论函数,这相当于说,从小到大遍历所有素数 𝑝 p 𝑛 n 𝑛 𝑝 n p Eratosthenes 筛法  的遍历顺序是一致的.因此,这一算法可以在 𝑂 ( 𝑛 l o g  l o g  𝑛 ) O ( n log  log  n ) 𝑛 n 
参考实现  这一计算方法可以推广到倍数和(拓展一)、乘积形式(拓展二)、利用完全积性函数代替常值函数(拓展三的推论)等拓展形式中.
例题 本节通过例题展示莫比乌斯反演的应用方法以及一些常见变形技巧.首先,通过一道例题熟悉处理求和式中最大公因数条件的基本技巧.
Luogu P2522 [HAOI 2011] Problem b 𝑇 T 
 𝑛 ∑ 𝑖 = 𝑥 𝑚 ∑ 𝑗 = 𝑦 [ g c d ( 𝑖 , 𝑗 ) = 𝑘 ] . ∑ i = x n ∑ j = y m [ gcd ( i , j ) = k ] . 数据范围:1   ≤ 𝑇 , 𝑥 , 𝑦 , 𝑛 , 𝑚 , 𝑘   ≤ 5   × 1 0 4 1 ≤ T , x , y , n , m , k ≤ 5 × 10 4 
解答  根据容斥原理,原式可以分成 4 4 
 𝑓 ( 𝑛 , 𝑚 , 𝑘 ) = 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 [ g c d ( 𝑖 , 𝑗 ) = 𝑘 ] . f ( n , m , k ) = ∑ i = 1 n ∑ j = 1 m [ gcd ( i , j ) = k ] . 对于这类式子,接下来是一段标准的推导流程:提取公因数,应用莫比乌斯函数性质,交换求和次序.
 首先,由于 𝑖 , 𝑗 i , j 𝑘 k 𝑖   = 𝑘 𝑖 ′ i = k i ′ 𝑗   = 𝑘 𝑗 ′ j = k j ′ 
 𝑓 ( 𝑛 , 𝑚 , 𝑘 ) = ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 ⌊ 𝑚 / 𝑘 ⌋ ∑ 𝑗 = 1 [ g c d ( 𝑖 , 𝑗 ) = 1 ] . f ( n , m , k ) = ∑ i = 1 ⌊ n / k ⌋ ∑ j = 1 ⌊ m / k ⌋ [ gcd ( i , j ) = 1 ] . 再利用莫比乌斯函数的性质可知:
 [ g c d ( 𝑖 , 𝑗 ) = 1 ] = ∑ 𝑑 ∣ g c d ( 𝑖 , 𝑗 ) 𝜇 ( 𝑑 ) = ∑ 𝑑 [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑗 ] 𝜇 ( 𝑑 ) . [ gcd ( i , j ) = 1 ] = ∑ d ∣ gcd ( i , j ) μ ( d ) = ∑ d [ d ∣ i ] [ d ∣ j ] μ ( d ) . 将它代入表达式,并交换求和次序,就得到:
 𝑓 ( 𝑛 , 𝑚 , 𝑘 ) = ∑ 𝑑 𝜇 ( 𝑑 ) ( ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 [ 𝑑 ∣ 𝑖 ] ) ( ⌊ 𝑚 / 𝑘 ⌋ ∑ 𝑗 = 1 [ 𝑑 ∣ 𝑗 ] ) . f ( n , m , k ) = ∑ d μ ( d ) ( ∑ i = 1 ⌊ n / k ⌋ [ d ∣ i ] ) ( ∑ j = 1 ⌊ m / k ⌋ [ d ∣ j ] ) . 这样一段操作的好处是,固定 𝑑 d 𝑖 i 𝑗 j 
 ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 [ 𝑑 ∣ 𝑖 ] = ⌊ ⌊ 𝑛 / 𝑘 ⌋ 𝑑 ⌋ ,   ⌊ 𝑚 / 𝑘 ⌋ ∑ 𝑗 = 1 [ 𝑑 ∣ 𝑗 ] = ⌊ ⌊ 𝑚 / 𝑘 ⌋ 𝑑 ⌋ , ∑ i = 1 ⌊ n / k ⌋ [ d ∣ i ] = ⌊ ⌊ n / k ⌋ d ⌋ ,   ∑ j = 1 ⌊ m / k ⌋ [ d ∣ j ] = ⌊ ⌊ m / k ⌋ d ⌋ , 所以,有
 𝑓 ( 𝑛 , 𝑚 , 𝑘 ) = ∑ 𝑑 𝜇 ( 𝑑 ) ⌊ ⌊ 𝑛 / 𝑘 ⌋ 𝑑 ⌋ ⌊ ⌊ 𝑚 / 𝑘 ⌋ 𝑑 ⌋ . f ( n , m , k ) = ∑ d μ ( d ) ⌊ ⌊ n / k ⌋ d ⌋ ⌊ ⌊ m / k ⌋ d ⌋ . 用线性筛预处理完 𝜇 ( 𝑑 ) μ ( d ) 𝑂 ( 𝑁   + 𝑇 √ 𝑁 ) O ( N + T N ) 𝑁 N 𝑛 , 𝑚 n , m 𝑇 T 
参考代码   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 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 #include   <algorithm> 
#include   <iostream> 
using   namespace   std ; 
constexpr   int   N   =   50000 ; 
int   mu [ N   +   5 ],   p [ N   +   5 ]; 
bool   flg [ N   +   5 ]; 
void   init ()   { 
   int   tot   =   0 ; 
   mu [ 1 ]   =   1 ; 
   for   ( int   i   =   2 ;   i   <=   N ;   ++ i )   { 
     if   ( ! flg [ i ])   { 
       p [ ++ tot ]   =   i ; 
       mu [ i ]   =   -1 ; 
     } 
     for   ( int   j   =   1 ;   j   <=   tot   &&   i   *   p [ j ]   <=   N ;   ++ j )   { 
       flg [ i   *   p [ j ]]   =   true ; 
       if   ( i   %   p [ j ]   ==   0 )   { 
         mu [ i   *   p [ j ]]   =   0 ; 
         break ; 
       } 
       mu [ i   *   p [ j ]]   =   - mu [ i ]; 
     } 
   } 
   for   ( int   i   =   1 ;   i   <=   N ;   ++ i )   mu [ i ]   +=   mu [ i   -   1 ]; 
} 
int   solve ( int   n ,   int   m )   { 
   int   res   =   0 ; 
   for   ( int   i   =   1 ,   j ;   i   <=   min ( n ,   m );   i   =   j   +   1 )   { 
     j   =   min ( n   /   ( n   /   i ),   m   /   ( m   /   i )); 
     res   +=   ( mu [ j ]   -   mu [ i   -   1 ])   *   ( n   /   i )   *   ( m   /   i );    // 代推出来的式子 
   } 
   return   res ; 
} 
int   main ()   { 
   cin . tie ( nullptr ) -> sync_with_stdio ( false ); 
   int   T ,   a ,   b ,   c ,   d ,   k ; 
   init ();    // 预处理mu数组 
   cin   >>   T ; 
   for   ( int   i   =   1 ;   i   <=   T ;   i ++ )   { 
     cin   >>   a   >>   b   >>   c   >>   d   >>   k ; 
     // 根据容斥原理,1<=x<=b&&1<=y<=d范围中的答案数减去1<=x<=b&&1<=y<=c-1范围中的答案数和 
     //   1<=x<=a-1&&1<=y<=d范围中的答案数再加上1<=x<=a-1&&1<=y<=c-1范围中的答案数 
     //   即可得到a<=x<=b&&c<=y<=d范围中的答案数 
     // 这一步如果不懂可以画坐标图进行理解 
     cout   <<   solve ( b   /   k ,   d   /   k )   -   solve ( b   /   k ,   ( c   -   1 )   /   k )   - 
                 solve (( a   -   1 )   /   k ,   d   /   k )   +   solve (( a   -   1 )   /   k ,   ( c   -   1 )   /   k ) 
          <<   '\n' ; 
   } 
   return   0 ; 
} 
接下来的两道例题展示了枚举公因数的处理方法,并利用 筛法  计算一般积性函数的值.
SPOJ LCMSUM 𝑇 T 
 𝑛 ∑ 𝑖 = 1 l c m  ( 𝑖 , 𝑛 ) . ∑ i = 1 n lcm  ( i , n ) . 数据范围:1   ≤ 𝑇   ≤ 3   × 1 0 5 ,   1   ≤ 𝑛   ≤ 1 0 6 1 ≤ T ≤ 3 × 10 5 ,   1 ≤ n ≤ 10 6 
解答一  题目提供的是最小公倍数,但往往最大公因数更容易处理.所以,首先做变形:
 𝑓 ( 𝑛 ) = 𝑛 ∑ 𝑖 = 1 l c m  ( 𝑖 , 𝑛 ) = 𝑛 ∑ 𝑖 = 1 𝑖 ⋅ 𝑛 g c d ( 𝑖 , 𝑛 ) . f ( n ) = ∑ i = 1 n lcm  ( i , n ) = ∑ i = 1 n i ⋅ n gcd ( i , n ) . 将 𝑛 n 𝑘 k 
 𝑓 ( 𝑛 ) = 𝑛 ∑ 𝑘 ∣ 𝑛 𝑛 ∑ 𝑖 = 1 𝑖 𝑘 [ g c d ( 𝑖 , 𝑛 ) = 𝑘 ] . f ( n ) = n ∑ k ∣ n ∑ i = 1 n i k [ gcd ( i , n ) = k ] . 对于内层的求和式,这是最常见的含有最大公因数的情形,重复标准的处理流程,就有:
 𝑓 ( 𝑛 ) = 𝑛 ∑ 𝑘 ∣ 𝑛 𝑛 / 𝑘 ∑ 𝑖 = 1 𝑖 [ g c d ( 𝑖 , 𝑛 𝑘 ) = 1 ] = 𝑛 ∑ 𝑘 ∣ 𝑛 𝑛 / 𝑘 ∑ 𝑖 = 1 𝑖 ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑛 𝑘 ] = 𝑛 ∑ 𝑘 ∣ 𝑛 ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑛 𝑘 ] ( 𝑛 / 𝑘 ∑ 𝑖 = 1 𝑖 [ 𝑑 ∣ 𝑖 ] ) . f ( n ) = n ∑ k ∣ n ∑ i = 1 n / k i [ gcd ( i , n k ) = 1 ] = n ∑ k ∣ n ∑ i = 1 n / k i ∑ d μ ( d ) [ d ∣ i ] [ d ∣ n k ] = n ∑ k ∣ n ∑ d μ ( d ) [ d ∣ n k ] ( ∑ i = 1 n / k i [ d ∣ i ] ) . 再次地,关于 𝑖 i 𝑖   = 𝑑 𝑖 ′ i = d i ′ 
 𝑛 / 𝑘 ∑ 𝑖 = 1 𝑖 [ 𝑑 ∣ 𝑖 ] = 𝑑 1 2 ( 𝑛 𝑘 𝑑 + 1 ) 𝑛 𝑘 𝑑 = : 𝑑 𝐺 ( 𝑛 𝑘 𝑑 ) . ∑ i = 1 n / k i [ d ∣ i ] = d 1 2 ( n k d + 1 ) n k d =: d G ( n k d ) . 由此,就得到如下表达式:
 𝑓 ( 𝑛 ) = 𝑛 ∑ 𝑘 ∣ 𝑛 ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑛 𝑘 ] 𝑑 𝐺 ( 𝑛 𝑘 𝑑 ) . f ( n ) = n ∑ k ∣ n ∑ d μ ( d ) [ d ∣ n k ] d G ( n k d ) . 在枚举公因数之后,这样形式的二重求和式很常见.对于它,同样有固定的处理方法:将乘积设为新变量 ℓ   = 𝑘 𝑑 ℓ = k d 𝑑   ∣ ( 𝑛 / 𝑘 ) d ∣ ( n / k ) 𝑑   ∣ ℓ   ∣ 𝑛 d ∣ ℓ ∣ n 
 𝑓 ( 𝑛 ) = 𝑛 ∑ ℓ ∣ 𝑛 𝐺 ( 𝑛 ℓ ) ∑ 𝑑 ∣ ℓ 𝜇 ( 𝑑 ) 𝑑 . f ( n ) = n ∑ ℓ ∣ n G ( n ℓ ) ∑ d ∣ ℓ μ ( d ) d . 设 𝐹 ( ℓ )   = ∑ 𝑑 ∣ ℓ 𝜇 ( 𝑑 ) 𝑑 F ( ℓ ) = ∑ d ∣ ℓ μ ( d ) d 
 𝑓 ( 𝑛 ) = 𝑛 ∑ ℓ ∣ 𝑛 𝐺 ( 𝑛 ℓ ) 𝐹 ( ℓ ) . f ( n ) = n ∑ ℓ ∣ n G ( n ℓ ) F ( ℓ ) . 因为 𝜇 ( 𝑑 ) 𝑑 μ ( d ) d 1 1 𝐹 ( 𝑛 ) F ( n ) 𝐺 ( 𝑛 ) G ( n ) 𝐺 ( 𝑛 ) G ( n ) 
 𝑓 ( 𝑛 ) = 1 2 𝑛 ( ∑ ℓ ( 𝑛 ℓ ) 2 𝐹 ( ℓ ) + ∑ ℓ 𝑛 ℓ 𝐹 ( ℓ ) ) . f ( n ) = 1 2 n ( ∑ ℓ ( n ℓ ) 2 F ( ℓ ) + ∑ ℓ n ℓ F ( ℓ ) ) . 这两项(不包含系数)都是积性函数,可以直接通过线性筛预处理(或者也可以线性筛出内层函数后,用 Dirichlet 前缀和在 𝑂 ( 𝑁 l o g  l o g  𝑁 ) O ( N log  log  N ) 
 𝐻 𝑠 ( 𝑛 ) = ∑ ℓ ( 𝑛 ℓ ) 𝑠 𝐹 ( ℓ ) ,   𝑠 = 1 , 2 . H s ( n ) = ∑ ℓ ( n ℓ ) s F ( ℓ ) ,   s = 1 , 2. 要推导它们的表达式,只需要确定它们在素数幂处的取值即可.为此,对于素数 𝑝 p 𝑒 e 
 𝐹 ( 𝑝 𝑒 ) = 𝜇 ( 1 ) + 𝜇 ( 𝑝 ) 𝑝 + 𝑒 ∑ 𝑗 = 2 𝜇 ( 𝑝 𝑗 ) 𝑝 𝑗 = 1 − 𝑝 , 𝐻 𝑠 ( 𝑝 𝑒 ) = ( 𝑝 𝑒 ) 𝑠 𝐹 ( 1 ) + 𝑒 ∑ 𝑗 = 1 ( 𝑝 𝑒 − 𝑗 ) 𝑠 𝐹 ( 𝑝 𝑗 ) = 𝑝 𝑒 𝑠 + ( 1 − 𝑝 ) 1 − 𝑝 𝑒 𝑠 1 − 𝑝 𝑠 ,   𝑠 = 1 , 2 . F ( p e ) = μ ( 1 ) + μ ( p ) p + ∑ j = 2 e μ ( p j ) p j = 1 − p , H s ( p e ) = ( p e ) s F ( 1 ) + ∑ j = 1 e ( p e − j ) s F ( p j ) = p e s + ( 1 − p ) 1 − p e s 1 − p s ,   s = 1 , 2. 特别地,𝐻 1 ( 𝑝 𝑒 )   ≡ 1 H 1 ( p e ) ≡ 1 
 𝐻 2 ( 𝑝 𝑒 ) = 𝑝 2 𝑒 + ( 1 − 𝑝 ) 1 − 𝑝 2 𝑒 1 − 𝑝 2 = 𝐻 2 ( 𝑝 𝑒 − 1 ) + 𝑝 2 𝑒 − 𝑝 2 𝑒 − 1 . H 2 ( p e ) = p 2 e + ( 1 − p ) 1 − p 2 e 1 − p 2 = H 2 ( p e − 1 ) + p 2 e − p 2 e − 1 . 这就很容易通过线性筛求解.在线性筛预处理出 𝐻 2 ( 𝑛 ) H 2 ( n ) 𝑓 ( 𝑛 )   = ( 𝑛 / 2 ) ( 𝐻 2 ( 𝑛 )   + 1 ) f ( n ) = ( n / 2 ) ( H 2 ( n ) + 1 ) 𝑂 ( 1 ) O ( 1 ) 𝑂 ( 𝑁   + 𝑇 ) O ( N + T ) 𝑁 N 𝑛 n 𝑇 T 
 参考实现中,利用本题表达式的特殊性,对线性筛部分做了进一步推导,这并非必须的.仅利用素数幂处的取值,仍然可以在 𝑂 ( 𝑁 ) O ( N ) 
解答二  就本题而言,有着更为灵活的处理方法.从解答一可以看出
 𝑓 ( 𝑛 ) = 𝑛 ∑ 𝑘 ∣ 𝑛 𝑛 / 𝑘 ∑ 𝑖 = 1 𝑖 [ g c d ( 𝑖 , 𝑛 𝑘 ) = 1 ] = 𝑛 ∑ 𝑘 ∣ 𝑛 𝐹 ( 𝑛 𝑘 ) . f ( n ) = n ∑ k ∣ n ∑ i = 1 n / k i [ gcd ( i , n k ) = 1 ] = n ∑ k ∣ n F ( n k ) . 如果在这一步不继续做莫比乌斯反演,而是观察后面的求和式实际上是不超过 𝑑   = 𝑛 / 𝑘 d = n / k 𝑑   > 1 d > 1 𝑑 d 𝑖 i 𝑑   − 𝑖 d − i 𝑑 d 
 𝐹 ( 𝑑 ) = 𝑛 ′ ∑ 𝑖 = 1 𝑖 [ 𝑖 ⟂ 𝑑 ] = 𝑑 ∑ 𝑖 = 1 ( 𝑑 − 𝑖 ) [ 𝑖 ⟂ 𝑑 ] = 1 2 𝑑 𝑑 ∑ 𝑖 = 1 [ 𝑖 ⟂ 𝑑 ] = 1 2 𝑑 𝜑 ( 𝑑 ) . F ( d ) = ∑ i = 1 n ′ i [ i ⟂ d ] = ∑ i = 1 d ( d − i ) [ i ⟂ d ] = 1 2 d ∑ i = 1 d [ i ⟂ d ] = 1 2 d φ ( d ) . 对于 𝑑   = 1 d = 1 
 𝐹 ( 𝑑 ) = 1 = 1 2 + 1 2 𝑑 𝜑 ( 𝑑 ) . F ( d ) = 1 = 1 2 + 1 2 d φ ( d ) . 进而,原式可以表示为
 𝑓 ( 𝑛 ) = 1 2 𝑛 ⎛ ⎜ ⎜ ⎝ ∑ 𝑑 ∣ 𝑛 𝑑 𝜑 ( 𝑑 ) + 1 ⎞ ⎟ ⎟ ⎠ . f ( n ) = 1 2 n ( ∑ d ∣ n d φ ( d ) + 1 ) . 由于 𝐺 ( 𝑛 )   = ∑ 𝑑 ∣ 𝑛 𝑑 𝜑 ( 𝑑 ) G ( n ) = ∑ d ∣ n d φ ( d ) 𝑛 𝜑 ( 𝑛 ) n φ ( n ) 1 1 𝑝 p 𝑒 e 
 𝐺 ( 𝑝 𝑒 ) = 1 + 𝑒 ∑ 𝑖 = 1 𝑝 𝑒 ( 𝑝 𝑒 − 1 ) = 𝐺 ( 𝑝 𝑒 − 1 ) + 𝑝 2 𝑒 − 𝑝 2 𝑒 − 1 . G ( p e ) = 1 + ∑ i = 1 e p e ( p e − 1 ) = G ( p e − 1 ) + p 2 e − p 2 e − 1 . 可以看出,这一表达式和解答一推导的结果是一致的.这一方法的总时间复杂度仍然是 𝑂 ( 𝑁   + 𝑇 ) O ( N + T ) 
 最后,利用本题积性函数的表达式,可以进一步优化线性筛的计算过程.对于素数 𝑝 p 
 𝐺 ( 𝑝 ) = 1 − 𝑝 + 𝑝 2 . G ( p ) = 1 − p + p 2 . 线性筛的关键在于对于一般的 𝑛 n 𝐺 ( 𝑝 𝑛 ) G ( p n ) 𝑝   ⟂ 𝑛 p ⟂ n 𝐺 G 
 𝐺 ( 𝑝 𝑛 ) = 𝐺 ( 𝑝 ) 𝐺 ( 𝑛 ) . G ( p n ) = G ( p ) G ( n ) . 否则,当 𝑝   ∣ 𝑛 p ∣ n 𝑛   = 𝑝 𝑒 𝑚 n = p e m 𝑝   ⟂ 𝑚 p ⟂ m 
 𝐺 ( 𝑝 𝑛 ) = 𝐺 ( 𝑝 𝑒 + 1 ) 𝐺 ( 𝑚 ) = 𝐺 ( 𝑝 𝑒 ) 𝐺 ( 𝑚 ) + ( 𝑝 2 𝑒 + 2 − 𝑝 2 𝑒 + 1 ) 𝐺 ( 𝑚 ) = 𝐺 ( 𝑛 ) + ( 𝑝 2 𝑒 + 2 − 𝑝 2 𝑒 + 1 ) 𝐺 ( 𝑚 ) . G ( p n ) = G ( p e + 1 ) G ( m ) = G ( p e ) G ( m ) + ( p 2 e + 2 − p 2 e + 1 ) G ( m ) = G ( n ) + ( p 2 e + 2 − p 2 e + 1 ) G ( m ) . 直接验证可知,这一表达式对于 𝑝   ⟂ 𝑛 p ⟂ n 
 𝐺 ( 𝑛 ) − 𝐺 ( 𝑛 𝑝 ) = ( 𝑝 2 𝑒 − 𝑝 2 𝑒 − 1 ) 𝐺 ( 𝑚 ) . G ( n ) − G ( n p ) = ( p 2 e − p 2 e − 1 ) G ( m ) . 代入上式,就得到
 𝐺 ( 𝑝 𝑛 ) = 𝐺 ( 𝑛 ) + 𝑝 2 ( 𝐺 ( 𝑛 ) − 𝐺 ( 𝑛 𝑝 ) ) . G ( p n ) = G ( n ) + p 2 ( G ( n ) − G ( n p ) ) . 这简化了线性筛部分的计算.当然,这一推导并非必需,对于没有特殊性质的积性函数,直接利用 𝐺 ( 𝑝 𝑛 )   = 𝐺 ( 𝑝 𝑒 + 1 ) 𝐺 ( 𝑚 ) G ( p n ) = G ( p e + 1 ) G ( m ) 
参考代码   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 
32 
33 
34 
35 
36 
37 
38 
39 #include   <iostream> 
constexpr   int   N   =   1000000 ; 
int   tot ,   p [ N   +   5 ]; 
long   long   g [ N   +   5 ]; 
bool   flg [ N   +   5 ];    // 标记数组 
void   solve ()   { 
   g [ 1 ]   =   1 ; 
   for   ( int   i   =   2 ;   i   <=   N ;   ++ i )   { 
     if   ( ! flg [ i ])   { 
       p [ ++ tot ]   =   i ; 
       g [ i ]   =   ( long   long ) 1   *   i   *   ( i   -   1 )   +   1 ; 
     } 
     for   ( int   j   =   1 ;   j   <=   tot   &&   i   *   p [ j ]   <=   N ;   ++ j )   { 
       flg [ i   *   p [ j ]]   =   true ; 
       if   ( i   %   p [ j ]   ==   0 )   { 
         g [ i   *   p [ j ]]   = 
             g [ i ]   +   ( g [ i ]   -   g [ i   /   p [ j ]])   *   p [ j ]   *   p [ j ];    // 代入推出来的式子 
         break ; 
       } 
       g [ i   *   p [ j ]]   =   g [ i ]   *   g [ p [ j ]]; 
     } 
   } 
} 
using   std :: cin ; 
using   std :: cout ; 
int   main ()   { 
   cin . tie ( nullptr ) -> sync_with_stdio ( false ); 
   int   T ,   n ; 
   solve ();    // 预处理g数组 
   cin   >>   T ; 
   for   ( int   i   =   1 ;   i   <=   T ;   ++ i )   { 
     cin   >>   n ; 
     cout   <<   ( g [ n ]   +   1 )   *   n   /   2   <<   '\n' ; 
   } 
   return   0 ; 
} 
BZOJ 2154 [国家集训队] Crash 的数字表格 求值:
 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 l c m  ( 𝑖 , 𝑗 ) m o d 2 0 1 0 1 0 0 9 . ∑ i = 1 n ∑ j = 1 m lcm  ( i , j ) mod 20101009. 数据范围:1   ≤ 𝑛 , 𝑚   ≤ 1 0 7 1 ≤ n , m ≤ 10 7 
解答  推导过程中忽略模数.设
 𝑓 ( 𝑛 , 𝑚 ) = 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 l c m  ( 𝑖 , 𝑗 ) . f ( n , m ) = ∑ i = 1 n ∑ j = 1 m lcm  ( i , j ) . 依然是将最小公倍数转换为最大公因数,枚举公因数,并应用标准的处理流程,就得到
 𝑓 ( 𝑛 , 𝑚 ) = ∑ 𝑘 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 𝑖 𝑗 𝑘 [ g c d ( 𝑖 , 𝑗 ) = 𝑘 ] = ∑ 𝑘 ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 ⌊ 𝑚 / 𝑘 ⌋ ∑ 𝑗 = 1 𝑘 𝑖 𝑗 [ g c d ( 𝑖 , 𝑗 ) = 1 ] = ∑ 𝑘 ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 ⌊ 𝑚 / 𝑘 ⌋ ∑ 𝑗 = 1 𝑘 𝑖 𝑗 ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑗 ] = ∑ 𝑘 𝑘 ∑ 𝑑 𝜇 ( 𝑑 ) ( ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 𝑖 [ 𝑑 ∣ 𝑖 ] ) ( ⌊ 𝑚 / 𝑘 ⌋ ∑ 𝑗 = 1 𝑗 [ 𝑑 ∣ 𝑗 ] ) . f ( n , m ) = ∑ k ∑ i = 1 n ∑ j = 1 m i j k [ gcd ( i , j ) = k ] = ∑ k ∑ i = 1 ⌊ n / k ⌋ ∑ j = 1 ⌊ m / k ⌋ k i j [ gcd ( i , j ) = 1 ] = ∑ k ∑ i = 1 ⌊ n / k ⌋ ∑ j = 1 ⌊ m / k ⌋ k i j ∑ d μ ( d ) [ d ∣ i ] [ d ∣ j ] = ∑ k k ∑ d μ ( d ) ( ∑ i = 1 ⌊ n / k ⌋ i [ d ∣ i ] ) ( ∑ j = 1 ⌊ m / k ⌋ j [ d ∣ j ] ) . 再次地,求和式对于 𝑖 i 𝑗 j 𝑖   = 𝑑 𝑖 ′ i = d i ′ 
 ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 𝑖 [ 𝑑 ∣ 𝑖 ] = 𝑑 ⌊ ⌊ 𝑛 / 𝑘 ⌋ / 𝑑 ⌋ ∑ 𝑖 = 1 𝑖 = 𝑑 𝐺 ( ⌊ ⌊ 𝑛 / 𝑘 ⌋ 𝑑 ⌋ ) = 𝑑 𝐺 ( ⌊ 𝑛 𝑘 𝑑 ⌋ ) . ∑ i = 1 ⌊ n / k ⌋ i [ d ∣ i ] = d ∑ i = 1 ⌊ ⌊ n / k ⌋ / d ⌋ i = d G ( ⌊ ⌊ n / k ⌋ d ⌋ ) = d G ( ⌊ n k d ⌋ ) . 其中,𝐺 ( 𝑛 )   = 1 2 𝑛 ( 𝑛   + 1 ) G ( n ) = 1 2 n ( n + 1 ) 特性 .对称地,对于另一个和式可以类似计算.代回前文表达式,就有
 𝑓 ( 𝑛 , 𝑚 ) = ∑ 𝑘 𝑘 ∑ 𝑑 𝜇 ( 𝑑 ) 𝑑 2 𝐺 ( ⌊ 𝑛 𝑘 𝑑 ⌋ ) 𝐺 ( ⌊ 𝑚 𝑘 𝑑 ⌋ ) . f ( n , m ) = ∑ k k ∑ d μ ( d ) d 2 G ( ⌊ n k d ⌋ ) G ( ⌊ m k d ⌋ ) . 和前文的情形一致,对于这类枚举公因数的式子,往往都需要枚举乘积 ℓ   = 𝑘 𝑑 ℓ = k d 
 𝑓 ( 𝑛 , 𝑚 ) = ∑ ℓ ⎛ ⎜ ⎜ ⎝ ∑ 𝑑 ∣ ℓ 𝜇 ( 𝑑 ) 𝑑 ℓ ⎞ ⎟ ⎟ ⎠ 𝐺 ( ⌊ 𝑛 ℓ ⌋ ) 𝐺 ( ⌊ 𝑚 ℓ ⌋ ) . f ( n , m ) = ∑ ℓ ( ∑ d ∣ ℓ μ ( d ) d ℓ ) G ( ⌊ n ℓ ⌋ ) G ( ⌊ m ℓ ⌋ ) . 设
 𝐹 ( ℓ ) = ∑ 𝑑 ∣ ℓ 𝜇 ( 𝑑 ) 𝑑 ℓ . F ( ℓ ) = ∑ d ∣ ℓ μ ( d ) d ℓ . 这是积性函数 ℓ ℓ ∑ 𝑑 ∣ ℓ 𝜇 ( 𝑑 ) 𝑑 ∑ d ∣ ℓ μ ( d ) d 𝑓 ( 𝑛 , 𝑚 ) f ( n , m ) 𝑂 ( m i n { 𝑛 , 𝑚 } ) O ( min { n , m } ) 
参考代码   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 
32 
33 
34 
35 
36 
37 
38 
39 #include   <algorithm> 
#include   <iostream> 
#include   <vector> 
int   main ()   { 
   constexpr   int   M   =   20101009 ; 
   int   n ,   m ; 
   std :: cin   >>   n   >>   m ; 
   if   ( n   >   m )   std :: swap ( n ,   m ); 
   std :: vector < int >   f ( n   +   1 ),   vis ( n   +   1 ),   prime ; 
   prime . reserve ( n ); 
   f [ 1 ]   =   1 ; 
   for   ( int   x   =   2 ;   x   <=   n ;   ++ x )   { 
     if   ( ! vis [ x ])   { 
       prime . emplace_back ( x ); 
       f [ x ]   =   1   -   x ; 
     } 
     for   ( int   p   :   prime )   { 
       if   ( 1L L   *   p   *   x   >   n )   break ; 
       vis [ x   *   p ]   =   1 ; 
       f [ x   *   p ]   =   x   %   p   ?   ( 1   -   p )   *   f [ x ]   :   f [ x ]; 
       if   ( x   %   p   ==   0 )   break ; 
     } 
   } 
   for   ( int   x   =   1 ;   x   <=   n ;   ++ x )   { 
     f [ x ]   =   1L L   *   x   *   f [ x ]   %   M   +   M ; 
     f [ x ]   =   ( f [ x ]   +   f [ x   -   1 ])   %   M ; 
   } 
   long   long   res   =   0 ; 
   for   ( int   l   =   1 ,   r ;   l   <=   n ;   l   =   r   +   1 )   { 
     int   nn   =   n   /   l ,   mm   =   m   /   l ; 
     r   =   std :: min ( n   /   nn ,   m   /   mm ); 
     int   g_n   =   ( 1L L   *   nn   *   ( nn   +   1 )   /   2 )   %   M ; 
     int   g_m   =   ( 1L L   *   mm   *   ( mm   +   1 )   /   2 )   %   M ; 
     res   +=   1L L   *   g_n   *   g_m   %   M   *   ( f [ r ]   -   f [ l   -   1 ]   +   M )   %   M ; 
   } 
   std :: cout   <<   ( res   %   M )   <<   '\n' ; 
   return   0 ; 
} 
接下来的一道例题较为特殊,需要对乘积的约数个数函数进行转换.
LOJ 2185. [SDOI2015] 约数个数和 𝑇 T 
 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 𝜎 0 ( 𝑖 𝑗 ) . ∑ i = 1 n ∑ j = 1 m σ 0 ( i j ) . 其中,𝜎 0 ( 𝑛 )   = ∑ 𝑑 ∣ 𝑛 1 σ 0 ( n ) = ∑ d ∣ n 1 𝑛 n 
 数据范围:1   ≤ 𝑛 , 𝑚 , 𝑇   ≤ 5   × 1 0 4 1 ≤ n , m , T ≤ 5 × 10 4 
解答  这道题目的难点在于将 𝜎 0 ( 𝑖 𝑗 ) σ 0 ( i j ) 𝜎 0 σ 0 𝑝 p 𝑒 1 , 𝑒 2 e 1 , e 2 𝑖   = 𝑝 𝑒 1 ,   𝑗   = 𝑝 𝑒 2 i = p e 1 ,   j = p e 2 
 𝜎 0 ( 𝑖 𝑗 ) = 1 + 𝑒 1 + 𝑒 2 = ∑ 𝑥 ∣ 𝑖 ∑ 𝑦 ∣ 𝑗 [ 𝑥 ⟂ 𝑦 ] . σ 0 ( i j ) = 1 + e 1 + e 2 = ∑ x ∣ i ∑ y ∣ j [ x ⟂ y ] . 对于一般情形,不妨设 𝑖   = ∏ 𝑝 𝑖 𝑝 i = ∏ p i p 𝑗   = ∏ 𝑝 𝑗 𝑝 j = ∏ p j p 𝑖 𝑝 , 𝑗 𝑝 i p , j p 𝑖 , 𝑗 i , j 𝑝 p 
 𝜎 0 ( 𝑖 𝑗 ) = ∏ 𝑝 𝜎 0 ( 𝑖 𝑝 𝑗 𝑝 ) = ∏ 𝑝 ∑ 𝑥 𝑝 ∣ 𝑖 𝑝 ∑ 𝑦 𝑝 ∣ 𝑗 𝑝 [ 𝑥 𝑝 ⟂ 𝑦 𝑝 ] . σ 0 ( i j ) = ∏ p σ 0 ( i p j p ) = ∏ p ∑ x p ∣ i p ∑ y p ∣ j p [ x p ⟂ y p ] . 注意到,对于 𝑖 i 𝑖 𝑝 i p 𝑥 𝑝 x p 𝑖 i 𝑥 x 𝑥 𝑝 x p 𝑗 j 
 𝜎 0 ( 𝑖 𝑗 ) = ∑ 𝑥 ∣ 𝑖 ∑ 𝑦 ∣ 𝑗 ∏ 𝑝 [ 𝑥 𝑝 ⟂ 𝑦 𝑝 ] = ∑ 𝑥 ∣ 𝑖 ∑ 𝑦 ∣ 𝑗 [ 𝑥 ⟂ 𝑦 ] . σ 0 ( i j ) = ∑ x ∣ i ∑ y ∣ j ∏ p [ x p ⟂ y p ] = ∑ x ∣ i ∑ y ∣ j [ x ⟂ y ] . 最后一步用到了结论:𝑥   ⟂ 𝑦 x ⟂ y 𝑝 p 𝑥 𝑝   ⟂ 𝑦 𝑝 x p ⟂ y p 
 得到这一表达式后,就可以应用标准的处理流程:
 𝜎 0 ( 𝑖 𝑗 ) = ∑ 𝑥 ∣ 𝑖 ∑ 𝑦 ∣ 𝑗 [ 𝑥 ⟂ 𝑦 ] = ∑ 𝑥 ∣ 𝑖 ∑ 𝑦 ∣ 𝑗 ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑥 ] [ 𝑑 ∣ 𝑦 ] = ∑ 𝑑 𝜇 ( 𝑑 ) ( ∑ 𝑥 [ 𝑑 ∣ 𝑥 ∣ 𝑖 ] ) ( ∑ 𝑦 [ 𝑑 ∣ 𝑦 ∣ 𝑗 ] ) = ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑗 ] 𝜎 0 ( 𝑖 𝑑 ) 𝜎 0 ( 𝑗 𝑑 ) . σ 0 ( i j ) = ∑ x ∣ i ∑ y ∣ j [ x ⟂ y ] = ∑ x ∣ i ∑ y ∣ j ∑ d μ ( d ) [ d ∣ x ] [ d ∣ y ] = ∑ d μ ( d ) ( ∑ x [ d ∣ x ∣ i ] ) ( ∑ y [ d ∣ y ∣ j ] ) = ∑ d μ ( d ) [ d ∣ i ] [ d ∣ j ] σ 0 ( i d ) σ 0 ( j d ) . 最后一步推导的含义是:函数只有在 𝑑   ∣ 𝑖 d ∣ i 𝑑   ∣ 𝑗 d ∣ j 𝑑   ∣ 𝑥   ∣ 𝑖 d ∣ x ∣ i 𝑥 x 𝑖 𝑑 i d 𝑥 𝑑 x d 𝑑   ∣ 𝑦   ∣ 𝑗 d ∣ y ∣ j 𝑦 y 
 将这一表达式再代回原式,并交换求和次序:
 𝑓 ( 𝑛 , 𝑚 ) = 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 𝜎 0 ( 𝑖 𝑗 ) = 𝑛 ∑ 𝑖 = 1 𝑚 ∑ 𝑗 = 1 ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑗 ] 𝜎 0 ( 𝑖 𝑑 ) 𝜎 0 ( 𝑗 𝑑 ) = ∑ 𝑑 𝜇 ( 𝑑 ) ( 𝑛 ∑ 𝑖 = 1 [ 𝑑 ∣ 𝑖 ] 𝜎 0 ( 𝑖 𝑑 ) ) ( 𝑚 ∑ 𝑗 = 1 [ 𝑑 ∣ 𝑗 ] 𝜎 0 ( 𝑗 𝑑 ) ) = ∑ 𝑑 𝜇 ( 𝑑 ) ( ⌊ 𝑛 / 𝑑 ⌋ ∑ 𝑖 = 1 𝜎 0 ( 𝑖 ) ) ( ⌊ 𝑚 / 𝑑 ⌋ ∑ 𝑗 = 1 𝜎 0 ( 𝑗 ) ) . f ( n , m ) = ∑ i = 1 n ∑ j = 1 m σ 0 ( i j ) = ∑ i = 1 n ∑ j = 1 m ∑ d μ ( d ) [ d ∣ i ] [ d ∣ j ] σ 0 ( i d ) σ 0 ( j d ) = ∑ d μ ( d ) ( ∑ i = 1 n [ d ∣ i ] σ 0 ( i d ) ) ( ∑ j = 1 m [ d ∣ j ] σ 0 ( j d ) ) = ∑ d μ ( d ) ( ∑ i = 1 ⌊ n / d ⌋ σ 0 ( i ) ) ( ∑ j = 1 ⌊ m / d ⌋ σ 0 ( j ) ) . 令 𝐺 ( 𝑛 )   = ∑ 𝑛 𝑖 = 1 𝜎 0 ( 𝑖 ) G ( n ) = ∑ i = 1 n σ 0 ( i ) 
 𝑓 ( 𝑛 , 𝑚 ) = ∑ 𝑑 𝜇 ( 𝑑 ) 𝐺 ( ⌊ 𝑛 𝑑 ⌋ ) 𝐺 ( ⌊ 𝑚 𝑑 ⌋ ) . f ( n , m ) = ∑ d μ ( d ) G ( ⌊ n d ⌋ ) G ( ⌊ m d ⌋ ) . 这可以通过数论分块求解.只需要预处理出 𝜇 ( 𝑛 ) μ ( n ) 𝜎 0 ( 𝑛 ) σ 0 ( n ) 𝑂 ( 𝑁   + 𝑇 √ 𝑁 ) O ( N + T N ) 𝑁 N 𝑛 , 𝑚 n , m 𝑇 T 
参考代码   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 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 #include   <algorithm> 
#include   <iostream> 
using   namespace   std ; 
constexpr   long   long   N   =   5e4   +   5 ; 
long   long   n ,   m ,   T ,   pr [ N ],   mu [ N ],   d [ N ],   t [ N ], 
     cnt ;    // t 表示 i 的最小质因子出现的次数 
bool   bp [ N ]; 
void   prime_work ( long   long   k )   { 
   bp [ 0 ]   =   bp [ 1 ]   =   true ,   mu [ 1 ]   =   1 ,   d [ 1 ]   =   1 ; 
   for   ( long   long   i   =   2 ;   i   <=   k ;   i ++ )   {    // 线性筛 
     if   ( ! bp [ i ])   pr [ ++ cnt ]   =   i ,   mu [ i ]   =   -1 ,   d [ i ]   =   2 ,   t [ i ]   =   1 ; 
     for   ( long   long   j   =   1 ;   j   <=   cnt   &&   i   *   pr [ j ]   <=   k ;   j ++ )   { 
       bp [ i   *   pr [ j ]]   =   true ; 
       if   ( i   %   pr [ j ]   ==   0 )   { 
         mu [ i   *   pr [ j ]]   =   0 ; 
         d [ i   *   pr [ j ]]   =   d [ i ]   /   ( t [ i ]   +   1 )   *   ( t [ i ]   +   2 ); 
         t [ i   *   pr [ j ]]   =   t [ i ]   +   1 ; 
         break ; 
       }   else   { 
         mu [ i   *   pr [ j ]]   =   - mu [ i ]; 
         d [ i   *   pr [ j ]]   =   d [ i ]   <<   1 ; 
         t [ i   *   pr [ j ]]   =   1 ; 
       } 
     } 
   } 
   for   ( long   long   i   =   2 ;   i   <=   k ;   i ++ ) 
     mu [ i ]   +=   mu [ i   -   1 ],   d [ i ]   +=   d [ i   -   1 ];    // 求前缀和 
} 
long   long   solve ()   { 
   long   long   res   =   0 ,   mxi   =   min ( n ,   m ); 
   for   ( long   long   i   =   1 ,   j ;   i   <=   mxi ;   i   =   j   +   1 )   {    // 整除分块 
     j   =   min ( n   /   ( n   /   i ),   m   /   ( m   /   i )); 
     res   +=   d [ n   /   i ]   *   d [ m   /   i ]   *   ( mu [ j ]   -   mu [ i   -   1 ]); 
   } 
   return   res ; 
} 
int   main ()   { 
   cin . tie ( nullptr ) -> sync_with_stdio ( false ); 
   cin   >>   T ; 
   prime_work ( 50000 );    // 预处理 
   while   ( T -- )   { 
     cin   >>   n   >>   m ; 
     cout   <<   solve ()   <<   '\n' ; 
   } 
   return   0 ; 
} 
最后一道例题展示了如何应用乘法版本的莫比乌斯反演.
Luogu P5221 Product 求值:
 𝑛 ∏ 𝑖 = 1 𝑛 ∏ 𝑗 = 1 l c m  ( 𝑖 , 𝑗 ) g c d ( 𝑖 , 𝑗 ) ( m o d 1 0 4 8 5 7 6 0 1 ) . ∏ i = 1 n ∏ j = 1 n lcm  ( i , j ) gcd ( i , j ) ( mod 104857601 ) . 数据范围:1   ≤ 𝑛   ≤ 1   × 1 0 6 1 ≤ n ≤ 1 × 10 6 
解答一  推导过程中忽略模数.设
 𝑓 ( 𝑛 ) = 𝑛 ∏ 𝑖 = 1 𝑛 ∏ 𝑗 = 1 l c m  ( 𝑖 , 𝑗 ) g c d ( 𝑖 , 𝑗 ) . f ( n ) = ∏ i = 1 n ∏ j = 1 n lcm  ( i , j ) gcd ( i , j ) . 依然是将最小公倍数转换为最大公因数:
 𝑓 ( 𝑛 ) = 𝑛 ∏ 𝑖 = 1 𝑛 ∏ 𝑗 = 1 𝑖 𝑗 ( g c d ( 𝑖 , 𝑗 ) ) 2 . f ( n ) = ∏ i = 1 n ∏ j = 1 n i j ( gcd ( i , j ) ) 2 . 注意,对这些因子的乘积是相互独立的,可以分别计算.令
 𝑔 ( 𝑛 ) = 𝑛 ∏ 𝑖 = 1 𝑛 ∏ 𝑗 = 1 g c d ( 𝑖 , 𝑗 ) . g ( n ) = ∏ i = 1 n ∏ j = 1 n gcd ( i , j ) . 原式就等于:
 𝑓 ( 𝑛 ) = ( 𝑛 ! ) 2 𝑛 𝑔 ( 𝑛 ) 2 . f ( n ) = ( n ! ) 2 n g ( n ) 2 . 重点是解决 𝑔 ( 𝑛 ) g ( n ) 
 𝑔 ( 𝑛 ) = ∏ 𝑘 𝑛 ∏ 𝑖 = 1 𝑛 ∏ 𝑗 = 1 𝑘 ↑ [ g c d ( 𝑖 , 𝑗 ) = 𝑘 ] = ∏ 𝑘 ⌊ 𝑛 / 𝑘 ⌋ ∏ 𝑖 = 1 ⌊ 𝑛 / 𝑘 ⌋ ∏ 𝑗 = 1 𝑘 ↑ [ g c d ( 𝑖 , 𝑗 ) = 1 ] . g ( n ) = ∏ k ∏ i = 1 n ∏ j = 1 n k ↑ [ gcd ( i , j ) = k ] = ∏ k ∏ i = 1 ⌊ n / k ⌋ ∏ j = 1 ⌊ n / k ⌋ k ↑ [ gcd ( i , j ) = 1 ] . 其中,𝑎   ↑ 𝑏   = 𝑎 𝑏 a ↑ b = a b [ g c d ( 𝑖 , 𝑗 )   = 1 ]   = ∑ 𝑑 𝜇 ( 𝑑 ) [ 𝑑   ∣ 𝑖 ] [ 𝑑   ∣ 𝑗 ] [ gcd ( i , j ) = 1 ] = ∑ d μ ( d ) [ d ∣ i ] [ d ∣ j ] 
 𝑔 ( 𝑛 ) = ∏ 𝑘 ∏ 𝑑 ⌊ 𝑛 / 𝑘 ⌋ ∏ 𝑖 = 1 ⌊ 𝑛 / 𝑘 ⌋ ∏ 𝑗 = 1 𝑘 ↑ ( 𝜇 ( 𝑑 ) [ 𝑑 ∣ 𝑖 ] [ 𝑑 ∣ 𝑗 ] ) . g ( n ) = ∏ k ∏ d ∏ i = 1 ⌊ n / k ⌋ ∏ j = 1 ⌊ n / k ⌋ k ↑ ( μ ( d ) [ d ∣ i ] [ d ∣ j ] ) . 进一步地提取因数(即令 𝑖   = 𝑑 𝑖 ′ i = d i ′ 𝑗   = 𝑑 𝑗 ′ j = d j ′ 特性 ,就得到:
 𝑔 ( 𝑛 ) = ∏ 𝑘 ∏ 𝑑 ⌊ 𝑛 / ( 𝑘 𝑑 ) ⌋ ∏ 𝑖 = 1 ⌊ 𝑛 / ( 𝑘 𝑑 ) ⌋ ∏ 𝑗 = 1 𝑘 ↑ 𝜇 ( 𝑑 ) . g ( n ) = ∏ k ∏ d ∏ i = 1 ⌊ n / ( k d ) ⌋ ∏ j = 1 ⌊ n / ( k d ) ⌋ k ↑ μ ( d ) . 然后分离关于 𝑖 , 𝑗 i , j 𝑖 , 𝑗 i , j 
 𝑔 ( 𝑛 ) = ∏ 𝑘 ∏ 𝑑 𝑘 ↑ ( 𝜇 ( 𝑑 ) ⌊ 𝑛 𝑘 𝑑 ⌋ 2 ) . g ( n ) = ∏ k ∏ d k ↑ ( μ ( d ) ⌊ n k d ⌋ 2 ) . 因为前面枚举了公因数,所以对于这个式子需要再次交换求乘积的次序.令 ℓ   = 𝑘 𝑑 ℓ = k d 
 𝑔 ( 𝑛 ) = ∏ ℓ ∏ 𝑑 ∣ ℓ ( ℓ 𝑑 ) ↑ ( 𝜇 ( 𝑑 ) ⌊ 𝑛 ℓ ⌋ 2 ) = ∏ ℓ ⎛ ⎜ ⎜ ⎝ ∏ 𝑑 ∣ ℓ ( ℓ 𝑑 ) ↑ 𝜇 ( 𝑑 ) ⎞ ⎟ ⎟ ⎠ ↑ ⌊ 𝑛 ℓ ⌋ 2 . g ( n ) = ∏ ℓ ∏ d ∣ ℓ ( ℓ d ) ↑ ( μ ( d ) ⌊ n ℓ ⌋ 2 ) = ∏ ℓ ( ∏ d ∣ ℓ ( ℓ d ) ↑ μ ( d ) ) ↑ ⌊ n ℓ ⌋ 2 . 设
 𝐹 ( 𝑛 ) = ∏ 𝑑 ∣ 𝑛 ( 𝑛 𝑑 ) ↑ 𝜇 ( 𝑑 ) . F ( n ) = ∏ d ∣ n ( n d ) ↑ μ ( d ) . 容易发现这是关于 ˜ 𝐹 ( 𝑛 )   = 𝑛 F ~ ( n ) = n Dirichlet 差分  方法在 𝑂 ( 𝑛 l o g  l o g  𝑛 ) O ( n log  log  n ) ˜ 𝐹 ( 𝑛 ) F ~ ( n ) 𝐹 ( 𝑛 ) F ( n ) 
 𝐹 ( 𝑛 ) = { 𝑝 , 𝑛 = 𝑝 𝑒 ,   𝑝 ∈ 𝐏 ,   𝑒 ∈ 𝐍 + , 1 , o t h e r w i s e . F ( n ) = { p , n = p e ,   p ∈ P ,   e ∈ N + , 1 , otherwise . von Mangoldt 函数  就是它的自然对数.得到 𝐹 ( 𝑛 ) F ( n ) 𝑂 ( √ 𝑛 ) O ( n ) 𝑔 ( 𝑛 ) g ( n ) 𝑓 ( 𝑛 ) f ( n ) 𝑂 ( 𝑛 ) O ( n ) 
 值得注意的是,涉及乘积的计算时,往往需要用到 欧拉定理 ,因此指数部分取模用到的模数与题目所给的模数并不相同.
解答二  乘积版本推导的难点在于对乘积和幂次的处理相对陌生,因此,对于这类问题,也可以取对数后再推导.对于本题,仅考虑 𝑔 ( 𝑛 ) g ( n ) 
 l o g  𝑔 ( 𝑛 ) = 𝑛 ∑ 𝑖 = 1 𝑛 ∑ 𝑗 = 1 l o g  g c d ( 𝑖 , 𝑗 ) . log  g ( n ) = ∑ i = 1 n ∑ j = 1 n log  gcd ( i , j ) . 对于这类含有最大公因数的式子,直接应用标准的推导流程,就得到:
 l o g  𝑔 ( 𝑛 ) = ∑ 𝑘 l o g  𝑘 𝑛 ∑ 𝑖 = 1 𝑛 ∑ 𝑗 = 1 [ g c d ( 𝑖 , 𝑗 ) = 𝑘 ] = ∑ 𝑘 l o g  𝑘 ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑗 = 1 [ g c d ( 𝑖 , 𝑗 ) = 1 ] = ∑ 𝑘 l o g  𝑘 ∑ 𝑑 𝜇 ( 𝑑 ) ( ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑖 = 1 [ 𝑖 ∣ 𝑑 ] ) ( ⌊ 𝑛 / 𝑘 ⌋ ∑ 𝑗 = 1 [ 𝑗 ∣ 𝑑 ] ) = ∑ 𝑘 l o g  𝑘 ∑ 𝑑 𝜇 ( 𝑑 ) ⌊ 𝑛 𝑘 𝑑 ⌋ 2 = ∑ ℓ ( ∑ 𝑑 𝜇 ( 𝑑 ) l o g  ℓ 𝑑 ) ⌊ 𝑛 ℓ ⌋ 2 = ∑ ℓ Λ ( ℓ ) ⌊ 𝑛 ℓ ⌋ 2 . log  g ( n ) = ∑ k log  k ∑ i = 1 n ∑ j = 1 n [ gcd ( i , j ) = k ] = ∑ k log  k ∑ i = 1 ⌊ n / k ⌋ ∑ j = 1 ⌊ n / k ⌋ [ gcd ( i , j ) = 1 ] = ∑ k log  k ∑ d μ ( d ) ( ∑ i = 1 ⌊ n / k ⌋ [ i ∣ d ] ) ( ∑ j = 1 ⌊ n / k ⌋ [ j ∣ d ] ) = ∑ k log  k ∑ d μ ( d ) ⌊ n k d ⌋ 2 = ∑ ℓ ( ∑ d μ ( d ) log  ℓ d ) ⌊ n ℓ ⌋ 2 = ∑ ℓ Λ ( ℓ ) ⌊ n ℓ ⌋ 2 . 其中,Λ ( 𝑛 ) Λ ( n ) von Mangoldt 函数 .将这一推导结果取幂,就得到解答一的结果.
参考代码   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 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 #include   <algorithm> 
#include   <iostream> 
#include   <vector> 
int   pow ( int   a ,   int   b ,   int   m )   { 
   int   res   =   1 ; 
   for   ( int   po   =   a ;   b ;   b   >>=   1 )   { 
     if   ( b   &   1 )   res   =   1L L   *   res   *   po   %   m ; 
     po   =   1L L   *   po   *   po   %   m ; 
   } 
   return   res ; 
} 
int   main ()   { 
   constexpr   int   M   =   104857601 ; 
   int   n ; 
   std :: cin   >>   n ; 
   // Get F(n), i.e., exp(Lambda(n)). 
   std :: vector < int >   vis ( n   +   1 ),   prime ,   pf ( n   +   1 ),   rem ( n   +   1 ); 
   prime . reserve ( n ); 
   for   ( int   x   =   2 ;   x   <=   n ;   ++ x )   { 
     if   ( ! vis [ x ])   { 
       prime . emplace_back ( x ); 
       pf [ x ]   =   x ; 
       rem [ x ]   =   1 ; 
     } 
     for   ( int   p   :   prime )   { 
       if   ( 1L L   *   p   *   x   >   n )   break ; 
       vis [ x   *   p ]   =   1 ; 
       pf [ x   *   p ]   =   p ; 
       rem [ x   *   p ]   =   x   %   p   ?   x   :   rem [ x ]; 
       if   ( x   %   p   ==   0 )   break ; 
     } 
   } 
   pf [ 1 ]   =   1 ; 
   for   ( int   x   =   2 ;   x   <=   n ;   ++ x )   { 
     pf [ x ]   =   rem [ x ]   ==   1   ?   pf [ x ]   :   1 ; 
   } 
   // Prefix products and their inverses. 
   std :: vector < int >   pm ( n   +   1 ),   ip ( n   +   1 ); 
   pm [ 0 ]   =   1 ; 
   for   ( int   x   =   1 ;   x   <=   n ;   ++ x )   { 
     pm [ x ]   =   1L L   *   pm [ x   -   1 ]   *   pf [ x ]   %   M ; 
   } 
   int   inv   =   pow ( pm [ n ],   M   -   2 ,   M ); 
   ip [ 0 ]   =   1 ; 
   for   ( int   x   =   n ;   x   >=   1 ;   -- x )   { 
     ip [ x ]   =   inv ; 
     inv   =   1L L   *   inv   *   pf [ x ]   %   M ; 
   } 
   // Calculate g(n). 
   int   res   =   1 ; 
   for   ( int   l   =   1 ,   r ;   l   <=   n ;   l   =   r   +   1 )   { 
     r   =   n   /   ( n   /   l ); 
     int   a   =   1L L   *   pm [ r ]   *   ip [ l   -   1 ]   %   M ; 
     int   b   =   1L L   *   ( n   /   l )   *   ( n   /   l )   %   ( M   -   1 ); 
     res   =   1L L   *   res   *   pow ( a ,   b ,   M )   %   M ; 
   } 
   // Take square and then inverse. 
   res   =   pow ( res ,   M   -   3 ,   M ); 
   // Get factorials. 
   int   fac   =   1 ; 
   for   ( int   x   =   1 ;   x   <=   n ;   ++ x )   { 
     fac   =   1L L   *   fac   *   x   %   M ; 
   } 
   // Final answer. 
   res   =   1L L   *   res   *   pow ( fac ,   2   *   n ,   M )   %   M ; 
   std :: cout   <<   res   <<   std :: endl ; 
   return   0 ; 
} 
习题 参考文献 2025/10/20 12:59:22 ,更新历史 在 GitHub 上编辑此页! Ir1d , StudyingFather , Enter-tainer , mgt , ShaoChenHeng , H-J-Granger , Marcythm , orzAtalod , Siyuan , sshwy , Early0v0 , Peanut-Tang , Xeonacid , countercurrent-time , ezoixx130 , hyp1231 , NachtgeistW , ranwen , c-forrest , GekkaSaori , ksyx , MegaOwIer , SamZhangQingChuan , Tiphereth-A , Vxlimo , 383494 , AngelKitty , CCXXXI , cjsoft , diauweb , Gesrua , Great-designer , guodong2005 , Henry-ZHR , HeRaNO , iamtwz , Konano , Lcyanstars , LovelyBuggies , Luckyblock233 , Makkiy , Menci , minghu6 , mxr612 , ouuan , P-Y-Y , PotassiumWings , Suyun514 , weiyong1024 , Chrogeek , CyaceQuious , FFjet , frank-xjh , GavinZhengOI , hehelego , hjsjhn , hydingsy , i-yyi , kenlig , kxccc , luojiny1 , lychees , nalemy , qwqAutomaton , shawlleyw , Sshwy , SukkaW , UserUnauthorized , WineChord , yjl9903 CC BY-SA 4.0  和 SATA