【学习笔记】数论函数与莫比乌斯反演
一. 数论函数基础
数论函数:满足值域为整数的函数。
本文下述的数若无特殊说明均为整数。
若无特殊说明则钦定
\(\displaystyle n=\prod_{i=1}^kp_i^{e_i},p_i\in\mathbb{P}\)。\(\mathbb{P}\) 表示质数集合,\(p_i\) 互不相同。
介绍几个常见的数论函数:
\(I(n)\):恒等函数,无论 \(n\) 是多少,其永远等于 \(1\)。
\(\epsilon(n)\):元函数,当 \(n=1\) 是值为 \(1\),否则为 \(0\)。它是狄利克雷卷积的单位元。
\(id(n)\):单位函数,无论 \(n\) 是多少,其值永远等于 \(n\)。
\(\varphi(n)\):欧拉函数,表示小于 \(n\) 的整数中与 \(n\) 互质的数的个数。
\(\mu(n)\):莫比乌斯函数,定义后文讲述。
积性函数
定义:对于函数 \(f\),若 \(n\bot m\)(即 \(n,m\) 互质)时有 \(f(nm)=f(n)f(m)\),则函数 \(f\) 为积性函数。
完全积性函数:对于函数 \(f\),有任意整数 \(n,m\) 有 \(f(nm)=f(n)f(m)\)。
显然 \(I(n),\epsilon(n),id(n)\) 都是完全积性函数。
显然完全积性函数是积性函数中的一种。
积性函数 \(f\) 有很多特殊性质:
-
\(f(1)=1\)
-
\(\displaystyle f(n)=\prod_{i=1}^kf(p_i^{e_i})\)
二. 欧拉函数
欧拉函数 \(\varphi(n)\) 是积性函数且不是完全积性函数。
证明欧拉函数 \(\varphi\) 是积性函数
知乎上这个问题有许多清晰的解法。这里给出其中一种。
首先证明一个重要定理:\(\displaystyle\varphi(n)=n\prod_{i=1}^k(\dfrac{p_i-1}{p_i})\)。
设 \(1\sim n\) 中与 \(n\) 至少有 \(i\) 个相同质数因子的数有 \(F_i(n)\) 个。
显然 \(F_0(n)=n\)。
\(\displaystyle F_1(n)=\sum_{i=1}^k\dfrac{n}{p_i}\)。
\(\displaystyle F_2(n)=\sum_{1\leq i<j\leq k}\dfrac{n}{p_ip_j}\)。
以下同理。
考虑容斥原理,得
容易发现式子即 \(\displaystyle\varphi(n)=n\prod_{i=1}^k(\dfrac{p_i-1}{p_i})\)。
有此定理后证明 \(\varphi(n)\) 是积性函数不难。
设 \(n\bot m\),\(\displaystyle n=\prod_{i=1}^kp_i^{e_i},m=\prod_{i=1}^{k'}q_i^{{E}_i}\)。
\(\therefore \displaystyle\varphi(n)=n\prod_{i=1}^k(\dfrac{p_i-1}{p_i}),\varphi(m)=m\prod_{i=1}^{k'}(\dfrac{q_i-1}{q_i})\)。
证毕。
欧拉函数的一些定理:
- \(\displaystyle\varphi(n)=n\prod_{i=1}^k(\dfrac{p_i-1}{p_i})\)
此定理等同于:\(\displaystyle \varphi(n)=\prod_{p^k||n}p^{k-1}(p-1)\)。
-
\(\varphi(p)=p-1,p\in \mathbb P\)
-
\(n\) 为奇数,\(\varphi(2n)=\varphi(n)\)。
-
\(\varphi(i\times p_j)=\begin{cases}\varphi(i)\varphi(p_j)&p_j\nmid i\\\varphi(i)p_j&p_j\mid i\end{cases}\)
-
\(\displaystyle n=\sum_{d|n}\varphi(d)\)
三. 狄利克雷卷积
对于两个数论函数 \(f(n),g(n)\),其狄利克雷卷积写作 \((f*g)(n)\),其中 \(f*g\) 可以看作是函数名称。
定义:\(\displaystyle (f*g)(n)=\sum_{d|n}f(d)g(\dfrac{n}{d})\)。
显然狄利克雷卷积满足交换律、结合律、分配律。
-
积性函数的狄利克雷卷积也是积性函数
设 \(f,g\) 为积性函数,\(\displaystyle h(n)=\sum_{d|n}f(d)g(\dfrac{n}{d})\)。
设 \(n,m,n\bot m\)。
\(\because n\bot m,\therefore \forall a|n,\forall b|m,a\bot b\)。
\(\displaystyle h(n)h(m)=\sum_{a|n}\sum_{b|m}f(ab)g(\dfrac{nm}{ab})=\sum_{d|nm}f(d)g(\dfrac{nm}{d})=h(nm)\)。
证毕。
-
积性函数的逆也是积性函数
逆:当 \(f*g=\epsilon\),\(f,g\) 互逆。
令 \(f\) 为积性函数,欲证 \(\forall n\bot m,g(nm)=g(n)g(m)\)。
考虑数学归纳法。
- \(nm=1\)
\(g(1)=1\),显然成立。
- \(nm>1\)
钦定当 \(n'm'<nm\) 时结论成立。
证毕。
四. 莫比乌斯反演
定义 \(I^{-1}\)(\(I\) 的逆)是 \(\mu\)。
那么若有 \(g=f*I\),得 \(f=g*\mu\)。
将其换一种写法,即得:
- 莫比乌斯反演:若 \(\displaystyle g(n)=\sum_{d|n}f(d)\),有 \(\displaystyle f(n)=\sum_{d|n}g(d)\mu(\dfrac{n}{d})\)。反之亦然。
那么考虑如何求出 \(\mu(n)\)。
由于 \(\mu\) 是 \(I\) 的逆,而 \(I\) 是积性函数,所以 \(\mu\) 也是积性函数。
显然得出 \(\mu(p^k)=\begin{cases}1&k=0\\-1&k=1\\0&k>1\end{cases}\)。
推广到一般数上,得:莫比乌斯函数 \(\mu(n)=\begin{cases}1&n=1\\0& \exists i\in[1,k],e_i>1\\(-1)^k &\text{otherwise}\end{cases}\)。
通过莫比乌斯反演有许多结论:
-
\(\displaystyle I(n)=\sum_{d|n}\epsilon(d)\Leftrightarrow \epsilon(n)=\sum_{d|n}\mu(d)\)
-
\(\displaystyle id(n)=\sum_{d|n}\varphi(d)\Leftrightarrow \varphi(n)=\sum_{d|n}\mu(\dfrac{n}{d})d\)
-
\(\varphi(n) *I(n)=id(n)\)
-
倍数莫比乌斯反演:若 \(\displaystyle g(n)=\sum_{n|d}f(d)\),有 \(\displaystyle f(n)=\sum_{n|d}g(d)\mu(\dfrac{d}{n})\)。
定义 \(\displaystyle (f\oplus g)(n)=\sum_{n|d}f(d)g(\dfrac{d}{n})\),易得 \((f*g)\oplus h=f\oplus (g\oplus h)\)。
那么 \(f=(\mu*I)\oplus f=\mu\oplus(I\oplus g)=\mu \oplus g\)。
五. 数论分块
求 \(\displaystyle \sum_{i=1}^n k\%i\)。
显然 \(k\%i=k-i\left\lfloor\dfrac{k}{i}\right\rfloor\)。
考虑一个问题:求 \(\displaystyle \sum_{i=1}^nf(i)\left\lfloor\dfrac{n}{i}\right\rfloor\)。(\(f(i)\) 为某数论函数)
显然 \(\left\lfloor\dfrac{n}{i}\right\rfloor\) 只有 \(2\sqrt n\) 种不同取值。
那么有 \(O(\sqrt n)\) 个块,对于每个块中所有数都相同。考虑对于同一块中两个数 \(\left\lfloor\dfrac{n}{i}\right\rfloor\) 与 \(\left\lfloor\dfrac{n}{j}\right\rfloor\),\(j\) 的最大值是 \(\left\lfloor\dfrac{n}{\left\lfloor\dfrac{n}{i}\right\rfloor}\right\rfloor\)。(也就是块长。)
所以对于一个块知道左端点就可以求出右端点。
而对于块 \([l,r]\) 贡献显然是 \(\displaystyle \sum_{i=l}^rf(i)\left\lfloor\dfrac{n}{l}\right\rfloor\)。
对于 \(f(i)\) 处理一个前缀和即可。
六. 莫反具体应用
求 \(1\le i,j\le n\) 且 \(\gcd(i,j)\in \mathbb P\) 的数对 \((i,j)\) 个数。
然后对于 \(\displaystyle \sum_{k|t,k\in \mathbb P}\mu(\frac{t}k)\) 设其等于 \(f(t)\),那么 \(f(t)\) 可以在 \(O(n\ln n)\) 内预处理。
而 $\displaystyle \sum_{t=1}n\left\lfloor\frac{n}{t}\right\rfloor2 $ 使用数论分块 \(O(\sqrt n)\)。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e7+8;
int n,s[N],p[N],mu[N],ans,cnt;
bool vis[N];
inline void init(){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt,i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
mu[i*p[j]]=-mu[i];
}
}
return;
}
signed main(){
scanf("%lld",&n);
init();
for(int i=1;i<=cnt;i++)for(int j=1;j*p[i]<=n;j++)s[j*p[i]]+=mu[j];
for(int i=2;i<=n;i++)s[i]+=s[i-1];
for(int i=1;i<=n;i++){
int l=i,r=(n/(n/l));
ans+=(s[r]-s[l-1])*(n/l)*(n/l);
i=r;
}
printf("%lld",ans);
return 0;
}
对于给出的 \(n\) 个询问,每次求有多少个数对 \((x,y)\),满足 \(a \le x \le b\),\(c \le y \le d\),且 \(\gcd(x,y) = k\)。
首先考虑一个弱化问题:将 \(a,c\) 变为 \(1\)。设此答案为 \(F(b,d)\)。
那么答案显然为 \(F(b,d)-F(b,c-1)-F(a-1,d)+F(a-1,c-1)\)。
那么问题转化为求 \(\displaystyle \sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k]\)。
那么这个也就是类似上一题。
设 \(d(x)\) 为 \(x\) 的约数个数,给定 \(n,m\),求
显然有个公式 \(\displaystyle d(ij)=\sum_{x|i}\sum_{y|j}\epsilon(\gcd(x,y))\)。
所求即为 \(\displaystyle \sum_{i=1}^n\sum_{j=1}^n\sum_{x|i}\sum_{y|j}\epsilon(\gcd(x,y))=\sum_{i=1}^n\sum_{j=1}^m\left\lfloor\frac{n}{i}\right\rfloor\left\lfloor\frac{m}{j}\right\rfloor\epsilon(\gcd(i,j))\)
。
那么设 \(\displaystyle f(x)=\sum_{i=1}^n\sum_{j=1}^m\left\lfloor\frac{n}{i}\right\rfloor\left\lfloor\frac{m}{j}\right\rfloor[\gcd(i,j)=x],g(x)=\sum_{x|d}f(d)\)。
答案即为 \(f(1)\)。
根据倍数莫比乌斯反演,有 \(\displaystyle f(x)=\sum_{x|d}g(d)\mu(\frac{d}{x})\)。
注意到当 \(d>n\) 时 \(g(d)\) 为 \(0\),所以 \(d\) 枚举到 \(n\)。
\(g(x)\) 使用数论分块做完。
//O(2)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5;
int T,n,m,s[N],p[N],mu[N],cnt,k,ans;
bool vis[N];
inline void init(){
mu[1]=1;
for(int i=2;i<N;i++){
if(!vis[i]){
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt,i*p[j]<N;j++){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
mu[i*p[j]]=-mu[i];
}
}
for(int i=1;i<N;i++)mu[i]+=mu[i-1];
for(int i=1;i<N;i++){
int res=0;
for(int I=1,j;I<=i;I=j+1){
j=i/(i/I);
res+=(j-I+1)*(i/I);
}
s[i]=res;
}
return;
}
signed main(){
init();
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&n,&m);
if(n>m)swap(n,m);
for(int i=1;i<=n;i++){
int l=i,r=min(n/(n/i),m/(m/i));
ans+=(mu[r]-mu[l-1])*s[n/l]*s[m/l];
i=r;
}
printf("%lld\n",ans);
ans=0;
}
return 0;
}