一.数论函数
1.定义
数论函数是 : 其定义域是正整数,值域是一个数集的函数。
积性函数 : 对于所有互质 整数 a a 和 b b 有性质f ( a b ) = f ( a ) f ( b ) f ( a b ) = f ( a ) f ( b ) 的数论函数。
完全积性函数 : 对于所有整数 a a 和 b b 有性质f ( a b ) = f ( a ) f ( b ) f ( a b ) = f ( a ) f ( b ) 的数论函数。
常见的的积性函数:
2.性质
1.对于任意正整数 n n , ∑ i | n φ ( i ) = n ∑ i | n φ ( i ) = n
不妨令 f ( n ) = ∑ i | n φ ( i ) f ( n ) = ∑ i | n φ ( i ) , 首先证明 f f 是一个积性函数。
因为 n , m n , m 互质
f ( n ) × f ( m ) = ∑ i | n φ ( i ) × ∑ j | m φ ( j ) = ∑ i j | n m φ ( i ) × φ ( j ) = ∑ i j | n m φ ( i j ) = f ( n × m ) f ( n ) × f ( m ) = ∑ i | n φ ( i ) × ∑ j | m φ ( j ) = ∑ i j | n m φ ( i ) × φ ( j ) = ∑ i j | n m φ ( i j ) = f ( n × m )
因为 n = p w 1 1 × p w 2 2 × . . . × p w k k n = p 1 w 1 × p 2 w 2 × . . . × p k w k , 且 f f 为积性函数 , 所以只需求出 f ( p w i i ) f ( p i w i ) 即可。
f ( p w i i ) = ∑ d | p w i i φ ( d ) = φ ( 1 ) + φ ( p i ) + φ ( p i 2 ) + . . . + φ ( p i w i ) = 1 + ( p i − 1 ) + ( p i 2 − p i ) + . . . + ( p i w i − p i w i − 1 ) = p i w i f ( p i w i ) = ∑ d | p i w i φ ( d ) = φ ( 1 ) + φ ( p i ) + φ ( p i 2 ) + . . . + φ ( p i w i ) = 1 + ( p i − 1 ) + ( p i 2 − p i ) + . . . + ( p i w i − p i w i − 1 ) = p i w i
所以 f ( n ) = n f ( n ) = n , 即 ∑ i | n φ ( i ) = n ∑ i | n φ ( i ) = n 。
2.对于任意正整数 n n , ∑ i | n μ ( i ) = [ n = 1 ] ∑ i | n μ ( i ) = [ n = 1 ]
证明如下:
1.当 n = 1 n = 1 时显然
2.当 n ! = 1 n ! = 1 时,由唯一分解定理得:n = p w 1 1 p w 2 2 . . . p w k k n = p 1 w 1 p 2 w 2 . . . p k w k
由莫比乌斯函数的性质,μ ( k ) ≠ 0 μ ( k ) ≠ 0 当且仅当 k k 无平方因子。(由多个质因子相乘)
有 i i 个质因子的数有 C i k C k i 种取值。
所以只需证
k ∑ i = 0 ( − 1 ) i C i k = 0 ∑ i = 0 k ( − 1 ) i C k i = 0
很像二项式定理,将 x = 1 , y = − 1 x = 1 , y = − 1 代入即可得证。
3.对于任意正整数 n n ,∑ d | n μ ( d ) d = φ ( n ) n ∑ d | n μ ( d ) d = φ ( n ) n
这个一会儿再证。
二.狄利克雷卷积
两个数论函数 f f 和 g g 的卷积为 t ( n ) = ( f × g ) ( n ) = ∑ d | n f ( d ) × g ( n d ) t ( n ) = ( f × g ) ( n ) = ∑ d | n f ( d ) × g ( n d ) 。
前面的括号代表将 f f 卷 g g ,后面的括号代表范围。
简记为t = f ∗ g t = f ∗ g 。
狄利克雷卷积满足交换律,结合律与分配律。
若 f f 是任意积性函数 , 则 f ∗ ϵ = f f ∗ ϵ = f
较为常见数论函数的迪利克雷卷积:
d = I ∗ I d = I ∗ I
σ = i d ∗ I σ = i d ∗ I
i d = φ ∗ I i d = φ ∗ I
ϵ = μ ∗ I ϵ = μ ∗ I
φ = μ ∗ i d φ = μ ∗ i d
其中,后三项分别对应积性函数的三个性质。
现在证一下 φ = μ ∗ i d φ = μ ∗ i d
φ ∗ I = i d ⇒ φ ∗ I ∗ μ = i d ∗ μ ⇒ φ = i d ∗ μ φ ∗ I = i d ⇒ φ ∗ I ∗ μ = i d ∗ μ ⇒ φ = i d ∗ μ
即
φ ( n ) = ∑ d | n n d ∗ μ ( d ) φ ( n ) = ∑ d | n n d ∗ μ ( d )
两边同时除以 n n , 得
φ ( n ) n = ∑ d | n μ ( d ) d φ ( n ) n = ∑ d | n μ ( d ) d
就是上文提到的性质3 3 。
三.数论分块
1.引入
题目给你这样一个式子:
n ∑ i = 1 ⌊ n i ⌋ ∑ i = 1 n ⌊ n i ⌋
这不是暴力吗?
那如果n ≤ 10 12 n ≤ 10 12 呢?再见
这时我们就要用到一个神奇的结论——数论分块
2.思想
再看一眼式子,我们发现,很多值是一样的。
如果我们知道分布规律,那么这一段就可以一起求解了。
结论是:若一段区间的左端点为l l ,那么区间值为 ⌊ n l ⌋ ⌊ n l ⌋ ,区间右端点 r = ⌊ n ⌊ n l ⌋ ⌋ r = ⌊ n ⌊ n l ⌋ ⌋
证明如下:
设 k = ⌊ n l ⌋ , p = n m o d l k = ⌊ n l ⌋ , p = n m o d l , 则n = k ∗ l + p n = k ∗ l + p
若 ⌊ n l + d ⌋ = k ⌊ n l + d ⌋ = k , 则 n = k ∗ ( l + d ) + p ′ n = k ∗ ( l + d ) + p ′
两个式子相减得:p ′ = p − k d p ′ = p − k d , 又因为 0 ≤ p , p ′ ≤ l − 1 0 ≤ p , p ′ ≤ l − 1
所以 d d 的最大值为 ⌊ p k ⌋ ⌊ p k ⌋ 。
那么,
r = l + d = l + ⌊ p k ⌋ = l + ⌊ n m o d l ⌊ n l ⌋ ⌋ = l + ⌊ n − ⌊ n l ⌋ ∗ l ⌊ n l ⌋ ⌋ = ⌊ l + n − ⌊ n l ⌋ ∗ l ⌊ n l ⌋ ⌋ = ⌊ ⌊ n l ⌋ ∗ l ⌊ n l ⌋ + n − ⌊ n l ⌋ ∗ l ⌊ n l ⌋ ⌋ = ⌊ n ⌊ n l ⌋ ⌋ r = l + d = l + ⌊ p k ⌋ = l + ⌊ n m o d l ⌊ n l ⌋ ⌋ = l + ⌊ n − ⌊ n l ⌋ ∗ l ⌊ n l ⌋ ⌋ = ⌊ l + n − ⌊ n l ⌋ ∗ l ⌊ n l ⌋ ⌋ = ⌊ ⌊ n l ⌋ ∗ l ⌊ n l ⌋ + n − ⌊ n l ⌋ ∗ l ⌊ n l ⌋ ⌋ = ⌊ n ⌊ n l ⌋ ⌋
3.代码实现
for ( int l = 1 , r ; l <= n ; l = r + 1 ) {
r = n / (n / l);
\\具体内容例题会讲到
}
数论分块大多数情况是和数论函数一起使用
4.例题
题目要求的是
n ∑ i = 1 k m o d i ∑ i = 1 n k m o d i
⇒ n ∑ i = 1 k − ⌊ k i ⌋ ∗ i ⇒ ∑ i = 1 n k − ⌊ k i ⌋ ∗ i
⇒ n ∗ k − n ∑ i = 1 ⌊ k i ⌋ ∗ i ⇒ n ∗ k − ∑ i = 1 n ⌊ k i ⌋ ∗ i
然后 ,因为在 l − r l − r 区间内 ⌊ k i ⌋ ⌊ k i ⌋ 的值相等,i i 递增,所以这段区间内是一个等差数列 ( 首项为 l ∗ ⌊ k i ⌋ l ∗ ⌊ k i ⌋ , 末项为 r ∗ ⌊ k i ⌋ r ∗ ⌊ k i ⌋ , 公差为 ⌊ k i ⌋ ⌊ k i ⌋ ) , 对于每一段区间计算和即可。
注意,A n s A n s 计算的是 ∑ n i = 1 ⌊ k i ⌋ ∗ i ∑ i = 1 n ⌊ k i ⌋ ∗ i 。
#include <cstdio>
#include <iostream>
using namespace std;
int n , k;
long long Ans;
int main ( ) {
scanf ("%d %d" ,&n,&k);
for ( int l = 1 , r ; l <= n ; l = r + 1 ) {
r = k / l == 0 ? n : min ( n , k / ( k / l ) );
Ans += 1ll * ( k / l ) * ( l + r ) * ( r - l + 1 ) / 2 ;
}
printf ("%lld" , 1ll * n * k - Ans );
return 0 ;
}
四.莫比乌斯函数与莫比乌斯反演
1.莫比乌斯函数
由唯一分解定理得:
n = p w 1 1 p w 2 2 . . . p w q q n = p 1 w 1 p 2 w 2 . . . p q w q
μ ( n ) = ⎧ ⎨ ⎩ 1 ( n = 1 ) ( − 1 ) q ( ∀ w i = 1 ) 0 ( ∃ w i ≥ 2 ) μ ( n ) = { 1 ( n = 1 ) ( − 1 ) q ( ∀ w i = 1 ) 0 ( ∃ w i ≥ 2 )
通俗来讲,μ ( 1 ) = 1 μ ( 1 ) = 1 ,当 n n 存在平方因子时 μ ( n ) = 0 μ ( n ) = 0
否则 μ ( n ) = ( − 1 ) k μ ( n ) = ( − 1 ) k , k k 为质因子数。
附一份线性筛的代码:
void sieve ( int x ) {
mu[ 1 ] = 1 ;
for ( int i = 2 ; i <= x ; i ++ ) {
if ( !vis[ i ] ) {
prime[ ++ k ] = i;
mu[ i ] = -1 ;
}
for ( int j = 1 ; j <= k && 1ll * i * prime[ j ] <= x ; j ++ ) {
vis[ i * prime[ j ] ] = 1 ;
if ( i % prime[ j ] == 0 ) break ;
mu[ i * prime[ j ] ] = -mu[ i ];
}
}
}
2.莫比乌斯反演
1.形式1
如果
F ( n ) = ∑ d | n f ( d ) F ( n ) = ∑ d | n f ( d )
则有
f ( n ) = ∑ d | n μ ( d ) F ( n d ) f ( n ) = ∑ d | n μ ( d ) F ( n d )
证法1.狄利克雷卷积
F = f ∗ I F = f ∗ I
F ∗ μ = f ∗ I ∗ μ F ∗ μ = f ∗ I ∗ μ
F ∗ μ = f ∗ ϵ F ∗ μ = f ∗ ϵ
f = F ∗ μ f = F ∗ μ
证法2.和式变化
∑ d | n μ ( d ) F ( n d ) = ∑ d | n μ ( d ) ∑ s | n d f ( s ) = ∑ d | n f ( d ) ∑ s | n d μ ( s ) = ∑ d | n f ( d ) [ n d = 1 ] = f ( n ) ∑ d | n μ ( d ) F ( n d ) = ∑ d | n μ ( d ) ∑ s | n d f ( s ) = ∑ d | n f ( d ) ∑ s | n d μ ( s ) = ∑ d | n f ( d ) [ n d = 1 ] = f ( n )
2.形式2
如果
F ( n ) = ∑ n | d f ( d ) F ( n ) = ∑ n | d f ( d )
则有
f ( n ) = ∑ n | d μ ( d ) F ( d n ) f ( n ) = ∑ n | d μ ( d ) F ( d n )
1.证法1.和式变化
∑ n | d μ ( d ) F ( d n ) = ∑ n | d μ ( d ) ∑ d n | s f ( s ) = ∑ n | d f ( d ) ∑ d n | s μ ( s ) = ∑ n | d f ( d ) [ d n = 1 ] = f ( n ) ∑ n | d μ ( d ) F ( d n ) = ∑ n | d μ ( d ) ∑ d n | s f ( s ) = ∑ n | d f ( d ) ∑ d n | s μ ( s ) = ∑ n | d f ( d ) [ d n = 1 ] = f ( n )
2.证法2.莫比乌斯函数
∑ n | d μ ( d ) F ( d n ) = ∑ n | d μ ( d n ) F ( d ) = ∑ n | d μ ( d n ) ∑ d | s f ( s ) ∑ n | d μ ( d ) F ( d n ) = ∑ n | d μ ( d n ) F ( d ) = ∑ n | d μ ( d n ) ∑ d | s f ( s )
因为 d d , s s 分别为 n n , d d 倍数, 所以设 d = n × k , s = d × t d = n × k , s = d × t ,上式即为
∑ k = 1 μ ( k ) ∑ t = 1 f ( ( k × t ) × n ) ∑ k = 1 μ ( k ) ∑ t = 1 f ( ( k × t ) × n )
观察发现,对于每一个 k k ,它会将所有的倍数贡献 μ ( k ) μ ( k ) 个。
反过来将,对于一个f ( a n ) f ( a n ) ,它出现的次数为∑ d | a μ ( d ) = [ a = 1 ] ∑ d | a μ ( d ) = [ a = 1 ] 。
所以只有当 a = 1 a = 1 时,f ( 1 ∗ n ) = f ( n ) f ( 1 ∗ n ) = f ( n ) 会刚好出现一次。
所以上式等于 f ( n ) f ( n ) 。
3.例题
1.Luogu P3455 求 ∑ n i = 1 ∑ m j = 1 [ g c d ( i , j ) = d ] ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] ( d d 已知 )
题解
2.Luogu P1829 求 ∑ n i = 1 ∑ m j = 1 l c m ( i , j ) ∑ i = 1 n ∑ j = 1 m l c m ( i , j )
题解
3.cqbzoj P6388 求 ∑ n i = 1 ∑ m j = 1 g c d ( i , j ) ∑ i = 1 n ∑ j = 1 m g c d ( i , j )
题解
4.Luogu P3704 求 ∑ n i = 1 ∑ m j = 1 f g c d ( i , j ) ∑ i = 1 n ∑ j = 1 m f g c d ( i , j ) , f f 为斐波拉契数列。
题解
五.杜教筛
一.前言
一般来说,反演的题目都需要积性函数的前缀和,一般都能用线性筛解决。
但是,如果良心出题人将 n n 出到 10 9 10 9 , 我们就需要使用一种非线性时间筛法。
二.推导
首先设要计算的函数为 f f , S S 为其前缀和。
构造出两个函数 g g , h h , 使得 h = f ∗ g h = f ∗ g , 即 h ( n ) = ∑ d | n f ( d ) ∗ g ( n d ) h ( n ) = ∑ d | n f ( d ) ∗ g ( n d )
显然有:
n ∑ i = 1 h ( i ) = n ∑ i = 1 ∑ d | i g ( i d ) ∗ f ( d ) = n ∑ i = 1 ∑ d b = i g ( d ) ∗ f ( b ) = n ∑ d = 1 g ( d ) ⌊ n d ⌋ ∑ b = 1 f ( b ) = n ∑ d = 1 g ( d ) S ( ⌊ n d ⌋ ) = g ( 1 ) S ( n ) + n ∑ d = 2 g ( d ) S ( ⌊ n d ⌋ ) ∑ i = 1 n h ( i ) = ∑ i = 1 n ∑ d | i g ( i d ) ∗ f ( d ) = ∑ i = 1 n ∑ d b = i g ( d ) ∗ f ( b ) = ∑ d = 1 n g ( d ) ∑ b = 1 ⌊ n d ⌋ f ( b ) = ∑ d = 1 n g ( d ) S ( ⌊ n d ⌋ ) = g ( 1 ) S ( n ) + ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ )
⇒ g ( 1 ) S ( n ) = n ∑ i = 1 h ( i ) − n ∑ d = 2 g ( d ) S ( ⌊ n d ⌋ ) ⇒ g ( 1 ) S ( n ) = ∑ i = 1 n h ( i ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ )
这就是杜教筛的一般形式了。
3.应用
一般来讲,在杜教筛时,h h 的前缀和可以快速求得 , g g 的前缀和也尽量简单。
大部分是狄利克雷卷积的形式。
1.求 S ( n ) = ∑ n i = 1 μ ( i ) S ( n ) = ∑ i = 1 n μ ( i )
容易想到 , μ ∗ I = ϵ μ ∗ I = ϵ , 即 g g 为 I I , h h 为 ϵ ϵ 。
代入上式得:
S ( n ) = 1 − n ∑ d = 2 S ( ⌊ n d ⌋ ) S ( n ) = 1 − ∑ d = 2 n S ( ⌊ n d ⌋ )
附一份代码:
int Summu ( int n ) {
if ( n <= MAXN ) return summ[ n ];
if ( Mapm[ n ] ) return Mapm[ n ];
int Ans = 1 ;
for ( int l = 2 , r ; l <= n ; l = r + 1 ) {
r = n / ( n / l );
Ans -= ( r - l + 1 ) * Summu ( n / l );
}
return Mapm[ n ] = Ans;
}
2.求 S ( n ) = ∑ n i = 1 φ ( i ) S ( n ) = ∑ i = 1 n φ ( i )
容易想到 , φ ∗ I = i d φ ∗ I = i d , 即 g g 为 I I , h h 为 i d i d 。
代入上式得:
S ( n ) = n ∗ ( n + 1 ) 2 − n ∑ d = 2 S ( ⌊ n d ⌋ ) S ( n ) = n ∗ ( n + 1 ) 2 − ∑ d = 2 n S ( ⌊ n d ⌋ )
附一份代码:
int Sumphi ( int n ) {
if ( n <= MAXN ) return sump[ n ];
if ( Mapp[ n ] ) return Mapp[ n ];
int Ans = n * ( n + 1 ) / 2 ;
for ( int l = 2 , r ; l <= n ; l = r + 1 ) {
r = n / ( n / l );
Ans -= ( r - l + 1 ) * Sumphi ( n / l );
}
return Mapp[ n ] = Ans;
}
结合 1 , 2 1 , 2 就是 P4213 【模板】杜教筛(Sum) 。
3.求 S ( n ) = ∑ n i = 1 φ ( i ) × i 2 S ( n ) = ∑ i = 1 n φ ( i ) × i 2
在迪利克雷卷积中,i d ∗ i d i d ∗ i d 会是一个非常好的式子,因为这样可以约分。
我们不妨构造函数 g ( n ) = n 2 g ( n ) = n 2 , 来约掉f ( n ) f ( n ) 所含的n 2 n 2 。
h ( n ) = ∑ d | n f ( d ) × g ( n d ) = ∑ d | n φ ( d ) × d 2 × ( n d ) 2 = n 2 ∑ d | n φ ( d ) = n 3 h ( n ) = ∑ d | n f ( d ) × g ( n d ) = ∑ d | n φ ( d ) × d 2 × ( n d ) 2 = n 2 ∑ d | n φ ( d ) = n 3
h , g h , g 前缀和非常容易得到
∑ n i = 1 h ( i ) = n 2 ( n + 1 ) 2 4 ∑ i = 1 n h ( i ) = n 2 ( n + 1 ) 2 4
∑ n i = 1 g ( i ) = n ( n + 1 ) ( 2 n + 1 ) 6 ∑ i = 1 n g ( i ) = n ( n + 1 ) ( 2 n + 1 ) 6
带入杜教筛的式子:
g ( 1 ) S ( n ) = n ∑ i = 1 h ( i ) − n ∑ d = 2 g ( d ) S ( ⌊ n d ⌋ ) g ( 1 ) S ( n ) = ∑ i = 1 n h ( i ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ )
S ( n ) = n 2 ( n + 1 ) 2 4 − n ∑ d = 2 g ( d ) S ( ⌊ n d ⌋ ) S ( n ) = n 2 ( n + 1 ) 2 4 − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ )
然后就可以做 P3768 简单的数学题
参考题解
4.求 S ( n ) = ∑ n i = 1 d ( i ) S ( n ) = ∑ i = 1 n d ( i )
首先有 d = I ∗ I d = I ∗ I
容易想到 , μ ∗ d = I μ ∗ d = I , 即 g g 为 μ μ , h h 为 I I 。
代入上式得:
S ( n ) = n − n ∑ d = 2 μ ( d ) S ( ⌊ n d ⌋ ) S ( n ) = n − ∑ d = 2 n μ ( d ) S ( ⌊ n d ⌋ )
然后可以用杜教筛同步筛 出 μ μ 和 d d 的前缀和。
原题 P6788 「EZEC-3」四月樱花
参考资料
数论函数
莫比乌斯反演
杜教筛
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现