狄利克雷卷积:
h(n)=∑d∣nf(d)g(dn)
另一种形式:
h(n)=∑xy=nf(x)g(y),是一样的。
性质:
- 满足交换律(易得,因为 d 和 dn 地位相同)
- 满足结合律((f∗g)∗h=f∗(g∗h))
- 满足对函数加法的分配律(f∗(g+h)=f∗g+f∗h)
- 如果 f,g 均为积性函数,则 f∗g 也为积性函数。
- f∗ϵ=f,其中 ϵ(n)=[n=1],[⋅] 为埃文斯括号。单位函数是狄利克雷卷积的单位元。
常见数论函数
- 单位函数 ϵ(n)=[n=1]
- 幂函数 idk(n)=nk,k=1 时为恒等函数 id(n)=n
- 欧拉函数 φ(n)
- 莫比乌斯函数 μ(n)
- 约数个数函数 d(n)=∑d∣n1
- 因数和函数 σ(n)=∑d∣nd
常用结论
1. φ∗1=id
证明:
方法1:
由于欧拉函数是积性函数,设
n=∏i=1kpici,只需证
n′=pc 时,
∑d∣n′φ(d)=n′ 即可。
由于
p 是质数,
d=p0,p1,p2,…,pc
因此
∑d∣n′φ(d)=∑i=0cφ(pi)=1+p0⋅(p−1)+p1⋅(p−1)+⋯+pc−1⋅(p−1)=1+(p−1)⋅p−1pc−1=pc
原命题得证。
方法2:
设
f(x) 为满足
gcd(k,n)=x(k≤n) 的
k 的个数,根据定义可知
n=∑i=0nf(i)(事实上,
i∣n 时
f(i) 才有值)
对
gcd(k,n)=x 两边同时除以
x:
得到
gcd(xk,xn)=1(k≤n)
会发现,满足上述条件的数的个数是
φ(xn)(这实际上是欧拉函数的定义)
∴f(x)=φ(xn)
∵n=∑d∣nf(d)
∴n=∑d∣nφ(dn)
即
id=1∗φ,Q.E.D
最终的到的式子相当于
n=∑d∣nφ(d)
这个式子十分关键。用
gcd(i,j) 替换掉
n 后,可进行如下变形:
gcd(i,j)=∑d∣gcd(i,j)φ(d)
=∑d∑i=1n[d∣i][d∣n]φ(d)
2. μ∗1=ϵ
证明:
设
n=∏i=1kpici,
n′=∏i=1kpi,要证
∑d∣nμ(d)=[n=1]
注意到
ci≥2 时对答案无贡献,因此
∑d∣nμ(d)=∑d∣n′μ(d)
考虑对于
n′ 的所有因子
d,答案实际上只和
d 包含的质因子个数
i 有关。枚举所有因子的过程可以看成从
k 个质因子中选
i(0≤i≤k) 个,有
(ik) 种选择方法,贡献为
(−1)i,
原式
=∑i=0k(ik)(−1)i
由二项式定理,这就是
(1+(−1))k
该式子当且仅当
k=0,即
n=1 时为
1,其余时候均为
0,这正好是
ϵ(n) 的意义,Q.E.D
有一个重要的反演结论可由此得出
[gcd(i,j)=1]=∑d∣gcd(i,j)μ(d)
证明: 只需将
n 替换成
gcd(i,j) 即可。
3. μ∗id=φ
φ∗1=id 等号两边同时卷
μ:
左边=φ∗(1∗μ)=φ∗ϵ=φ
右边=id∗μ=∑d∣nd⋅μ(dn)
因此可以得到
φ(n)=∑d∣nd⋅μ(dn)=∑d∣nμ(d)dn
4. 1∗1=d
5. id∗1=σ
6. d(i⋅j)=∑x∣i∑y∣j[gcd(x,y)=1]
莫比乌斯反演
形式一:
f(n)=∑d∣ng(n)⇔g(n)=∑d∣nμ(d)f(dn)
证明:
即已知
f=g∗1,求证
g=μ∗f
μ∗f=μ∗1∗g=ϵ∗g=g,Q.E.D
形式二:
f(n)=∑n∣dg(n)⇔g(n)=∑n∣dμ(d)f(nd)
证明:
不是常规狄利克雷卷积形式了,不能直接卷积证,但是可以代数变形,逆推该式子。
∑n∣dμ(d)f(nd)=∑n∣dμ(nd)f(d)
令
d=kn,枚举
k(这一步是为了把
n 单独拎出来,再代入
g)
=∑k=1+∞μ(k)f(kn)
=∑k=1+∞μ(k)∑kn∣dg(d)
交换枚举顺序(目的是为了利用
μ∗1=ϵ)
=∑n∣dg(d)∑k∣ndμ(k)
=∑n∣dg(d)ϵ(nd)
当且仅当
d=n 时,
ϵ(nd)=1.
Q.E.D
推式子常见思路
好题记录
题意:求
∑i=1N∑j=1Nlcm(ai,aj)
N≤5×104,1≤ai≤5×104.
ai 的性质是不优美的。考虑
改变变量意义(该技巧在本题内频繁出现),直接枚举数的值,设
ci 为
i 这个数在序列
a 中出现的次数,
n 为
a 中的最大数,则问题转化为:
∑i=1n∑j=1nci⋅cj⋅lcm(i,j)
=∑i=1n∑j=1nci⋅cj⋅gcd(i,j)i⋅j
这里有个常见技巧,令
g=gcd(i,j),枚举
g,并改变
i,j 意义为
i′=gi,j′=gj,则原式变为
=∑g=1ng∑i=1⌊gn⌋∑j=1⌊gn⌋cig⋅cjg⋅ij⋅[gcd(i,j)=1]
再进行莫比乌斯反演
=∑g=1ng∑i=1⌊gn⌋∑j=1⌊gn⌋cig⋅cjg⋅ij⋅∑d∣gcd(i,j)μ(d)
可以知
d∣i,d∣j。把
d 往前提出,并改变
i,j 意义为
i′=di,j′=dj,原式变为
=∑g=1ng⋅(∑d=1⌊gn⌋μ(d)⋅d2)⋅(∑i=1⌊gdn⌋∑j=1⌊gdn⌋cigd⋅i⋅cjgd⋅j)
=∑g=1ng⋅(∑d=1⌊gn⌋μ(d)⋅d2)⋅(∑i=1⌊gdn⌋cigd⋅i)2
然鹅这样还不可以实现预处理第一个括号,需要把两个括号互相独立。
考虑第一个括号实际上就是
∑gd=1nμ(d)⋅d2
注意此处
d 的含义不变。不妨枚举
k=gd,有
=∑k=1nk⋅(∑d∣kμ(d)⋅d)⋅(∑i=1⌊kn⌋i⋅cik)2
这样两个括号的范围就都只和
k 有关了,可以独立计算。
其中第一个括号可以进行
O(nlogn) 预处理,第二个括号可以暴力计算,总计算时间复杂度为
O(nlogn),可以通过本题。
Code:
CPP#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=50005;
int n,a[N];
int prime[N],cnt=0,mu[N],f[N],c[N];
bool vis[N];
void init(){
mu[1]=1;
for(int i=2;i<=N-5;i++){
if(!vis[i]){
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=N-5;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=-mu[i];
}
}
for(int i=1;i<=N-5;i++){
for(int j=i;j<=N-5;j+=i){
f[j]+=mu[i]*i;
}
}
}
signed main(){
init();
cin>>n;
int m=0;
for(int i=1;i<=n;i++){
cin>>a[i];
c[a[i]]++;
m=max(m,a[i]);
}
n=m;
int ans=0ll;
for(int k=1;k<=n;k++){
int tmp=0ll;
for(int i=1;i<=n/k;i++){
tmp+=i*c[i*k];
}
ans+=k*f[k]*tmp*tmp;
}
cout<<ans<<endl;
}