Dirichlet学习笔记
Dirichlet前缀和
狄利克雷前缀和是求解形如
b
k
=
∑
i
∣
k
a
i
b_k=\sum\limits_{i|k}a_i
bk=i∣k∑ai
的式子
首先我们可以想到枚举 i i i ,再枚举 i i i 的倍数 j j j b j = b j + a i b_j=b_j+a_i bj=bj+ai
此时的时间复杂度为 n / 1 + n / 2 + n / 3 + . . . + n / 1 n/1+n/2+n/3+...+n/1 n/1+n/2+n/3+...+n/1 。由于调和级数,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
进一步分析式子,我们可以发现一个较大的 b k b_k bk 可以分解为几个 b k 的因子 b_{k的因子} bk的因子 相加,例如 b 8 = a 1 + a 2 + a 3 + a 4 + a 8 b_8=a_1+a_2+a_3+a_4+a_8 b8=a1+a2+a3+a4+a8 , b 4 = a 1 + a 2 + a 3 + a 4 b_4=a_1+a_2+a_3+a_4 b4=a1+a2+a3+a4 , 所以 b 8 = b 4 + a 8 b_8=b_4+a_8 b8=b4+a8
而 8 = 2 ∗ 4 8=2*4 8=2∗4 ,我们可以考虑枚举质数因子,和质数的系数来求解。
例如
for(int i=1;i<=tot;i++){
for(int j=1;p[i]*j<=n;j++){
a[p[i]*j] += a[j];
}
}
p
[
i
]
p[i]
p[i] 为枚举的质数,
j
j
j为质数的系数,我们把
b
b
b 数组放到
a
a
a 数组中,节省空间更方便。
Dirichlet后缀和
后缀和和前缀和基本相同,只改变了赋值方向。
b k = ∑ k ∣ i a i b_k=\sum\limits_{k|i}a_i bk=k∣i∑ai
for(int i=1;i<=tot;i++){
for(int j=n/p[i];j>=1;j--){
a[j] += a[p[i]*j];
}
}
倒Dirichlet前缀和
a
k
=
∑
i
∣
k
b
i
a_k=\sum\limits_{i|k}b_i
ak=i∣k∑bi
给出
a
k
a_k
ak 求
b
i
b_i
bi。我们需要从大到小枚举
for(int i=tot;i>=1;i--){
for(int j=n/p[i];j>=1;j--){
a[p[i]*j] -= a[j];
}
}
倒Dirichlet后缀和
a k = ∑ k ∣ i b i a_k=\sum\limits_{k|i}b_i ak=k∣i∑bi
for(int i=tot;i>=1;i--){
for(int j=1;p[i]*j<=n;j++){
a[j] -= a[p[i]*j];
}
}
Dirichlet卷积
我们有数论函数 h h h 满足
h ( n ) = ∑ d ∣ n f ( d ) g ( n d ) h(n)=\sum\limits_{d|n}f(d)g(\dfrac{n}{d}) h(n)=d∣n∑f(d)g(dn)
或者
h ( n ) = ∑ i j = n f ( i ) g ( i ) h(n)=\sum\limits_{ij=n}f(i)g(i) h(n)=ij=n∑f(i)g(i)
则 h h h 为 f f f 和 g g g 的的狄利克雷卷积,记作 h = f ∗ g h=f*g h=f∗g
通过第二种形式,我们可以发现狄利克雷卷积具有结合律和交换律
( ( f ∗ g ) ∗ h ) ( n ) = ∑ i j k = n f ( i ) g ( i ) k ( i ) = ( f ∗ ( g ∗ h ) ) ( n ) ((f*g)*h)(n)=\sum\limits_{ijk=n}f(i)g(i)k(i)=(f*(g*h))(n) ((f∗g)∗h)(n)=ijk=n∑f(i)g(i)k(i)=(f∗(g∗h))(n)
此外若 f , g f,g f,g 为奇性函数, h h h 也是奇性函数。我们可以用这个性质判断某些函数是否为奇性函数。