狄利克雷卷积&莫比乌斯反演入门

狄利克雷卷积&莫比乌斯反演入门

狄利克雷卷积

数论函数

数论函数指一类定义域是正整数,值域是一个数集的函数。

加法:\((f+g)(x)=f(x)+g(x)\)

数乘:\((xf)(n)=x*f(n)\)

定义

定义两个数论函数的狄利克雷卷积*:

\(t=f*g\)\(t(n)=\Sigma_{i|n}f(i)g(\frac{n}{i})\),通俗说就是所有 \(xy=n\)\(t(n)=f(x)g(y)\)

狄利克雷卷积有以下性质:

  1. \(f=g\),当且仅当 \(f,g\) 的每一项都相等
  2. 交换律 \(f*g=g*f\)
  3. 结合律 \((f*g)*h=f*(g*h)\)
  4. 分配律 \(f∗h+g∗h=(f+g)∗h\)
  5. 数乘分配律 \((xf)∗g=x(f∗g)\)
  6. 单位元 \(\epsilon∗f=f\),其中 \(\epsilon(n)=[n=1]\) 对于每一个 \(f(1)≠0\) 的函数 \(f\),都有 \(f∗g=\epsilon\),其中 \(\epsilon\) 的定义与上相同

莫比乌斯反演

莫比乌斯反演函数

\(\large{\mu(d)=\left\{\begin{matrix} 1,\ d=1 \\0, \ \exists p^2|x,p\in Prime \\(-1)^k, \ k为质因数个数\end{matrix}\right.}\)

它有一些性质:

\(\large{\Sigma_{d|n(n\in\mathbb{N}^+)}\mu(d)= \left\{\begin{matrix} 1,\ n=1 \\0,\ n>1 \end{matrix}\right.}=[n=1]\)

这里给出一个ai写的证明

void init(){ // 线性筛求miu[]
	vector <int> p;
	miu[1] = 1;
	for(int i = 2; i <= N-5; i++){
		if(!v[i]){
			miu[i] = -1;
			p.pb(i);
		}
		for(auto j : p){
			if(j*i > N-5) break;
			v[j*i] = 1;
			if(i%j == 0) break;
			else miu[j*i] = -miu[i];
		}
	}
}

莫比乌斯反演公式

\(F(n),f(n)\ (n\in \mathbb{N}^+)\),且满足 \(F(n)=\Sigma_{d|n}f(d)\) 时,则 \(\large{f(n)=\Sigma_{d|n}\mu(d)F(\frac{n}{d})}\)

\(F(n),f(n)\ (n\in \mathbb{N}^+)\),且满足 \(F(d)=\Sigma_{d|n}f(n)\) 时,则 \(\large{f(d)=\Sigma_{d|n}F(n)\mu(\frac{n}{d})}\)

第一种形式的证明:

定义恒等函数 \(I(n)\)​,这个函数的值恒为1

根据上述的 \(\mu(n)\) 的性质 \(\large{\Sigma_{d|n}\mu(d)=[n=1]}\),易得 \(\mu*I=\epsilon\)

\(F(n)\) 的定义可推导:

\(F=f*I\)

\(F*\mu=f*I*\mu=f*\epsilon=f\)

\(f=F*\mu\)

代入后得 \(f(n)=\Sigma_{d|n}\mu(d)F(\frac{n}{d})\)

证毕。

第二种形式的证明:

\(\large{\sum_{d|n}\mu(d)f(\frac{n}{d})=\sum_{d|n}\mu(d)\sum_{k|\frac{n}{d}}g(k)=\sum_{k|n}g(k)\sum_{d|\frac{n}{k}}\mu(d)=g(n)}\)

证毕。

应用

莫反的题目大多都有一定的套路/公式,一定要多做题(水蓝紫题),在几道模板题的思路点拨后自己尝试推式子,熟练掌握该算法。

例题1

P3455 [POI 2007] ZAP-Queries

给定三个数 \(a,b,d\),设 \(x\in[1,a],y\in[1,b]\),求 \(\gcd(x,y)=d\) 的有序对 \((x,y)\)​​ 有多少对。

对于这类题,可以通过套路的设 \(f(d),F(n)\) 分别作为题目所求与一个满足莫反公式且方便求的两个数论函数求解

\(\large{f(d)=\sum_{i=1}^{a}\sum_{j=1}^{b}[\gcd(i,j)=d]}\),即答案所求

\(\large{F(d)=\sum_{d|n}f(n)=\lfloor \frac{a}{d}\rfloor\lfloor \frac{b}{d}\rfloor}\),即 \(\gcd(i,j)=d与d的倍数\) 的个数

由莫反公式可得

\(\large{ans=f(d)=\sum_{d|n}F(n)\mu(\frac{n}{d})}\)

枚举 \(\large{t=\frac{k}{d}}\),可得\(\large{ans=f(d)=\sum_{t=1}^{min(\lfloor \frac{a}{d}\rfloor,\lfloor \frac{b}{d}\rfloor)}\mu(t)\lfloor \frac{a}{td}\rfloor\lfloor \frac{b}{td}\rfloor}\)

到这里其实就已经可以以 \(O(a)\)​​ 的复杂度求解了,但原题还有多组样例,所以通过整除分块优化

整除分块可以从这里学习

最后复杂度为 \(O(\sqrt{a})\)

void init(){
    int n = 50000;
	for(int i = 1; i <= n; i++) miu[i] = 1;
	for(int i = 2; i <= n; i++){
		if(v[i]) continue;
		miu[i] = -1; // 为质数
		for(int j = 2; i*j <= n; j++){
			v[i*j] = 1;
			if(j%i == 0) miu[i*j] = 0;
			else miu[i*j] *= -1;
		}
	}
	for(ll i = 1; i <= n; i++) sum[i] = sum[i-1]+miu[i];
}
void solve(){
	a = read(), b = read(), d = read(), ans = 0;
	// for(ll i = 1; i <= min(a/d, b/d); i++){ // 此为原公式解法
	// 	ans += miu[i]*(a/(i*d))*(b/(i*d));
	// }
	for(ll l = 1, r; l <= min(a/d, b/d); l = r+1){
		r = min((a/d)/((a/d)/l), (b/d)/((b/d)/l));
		ans += ((a/d)/l)*((b/d)/l)*(sum[r]-sum[l-1]);
	}
	write(ans);
}

例题2

P2522 [HAOI2011] Problem b

给定五个数 \(a,b,c,d,k\),设 \(x\in[a,b],y\in[c,d]\),求 \(\gcd(x,y)=k\) 的有序对 \((x,y)\) 有多少对。

其实和上一题没啥区别,而值域的改变可以通过一个简单的容斥(类似前缀和)得到,这里不再赘述,就当双倍经验了

例题3

P2257 YY的GCD

给定两个数 \(n,m\), 设 \(x\in[1,n],y\in[1,m]\),求 \(\gcd(x,y)=p\ (p\in Prime)\)\(p\) 为质数的有序对 \((x,y)\) 有多少对。

我们继续设 \(\large{f(d)=\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=d],F(d)=\sum_{d|k}f(k)=\lfloor \frac{n}{d}\rfloor\lfloor \frac{m}{d}\rfloor}\)

由莫反公式得 \(\large{f(d)=\sum_{d|k}F(k)\mu(\lfloor \frac{k}{d}\rfloor)}\)

本题答案 \(\large{ans=\sum_{p\in Prime}f(p)=\sum_{p\in Prime}\sum_{p|k}F(k)\mu(\lfloor \frac{k}{p}\rfloor)}\)

\(\large{t=\frac{k}{p}}\),则 \(\large{ans=\sum_{p\in Prime}\sum_{t=1}^{min(\lfloor \frac{n}{p}\rfloor,\lfloor \frac{m}{p}\rfloor)}}\lfloor \frac{n}{pt}\rfloor\lfloor \frac{m}{pt}\rfloor\mu(t)\)

有于质数限制的存在,我们很难通过整除分块优化这个式子

所以我们考虑将从1开始的那个硬核枚举(即 \(\large{\sum_{t=1}^{min(\lfloor \frac{n}{p}\rfloor,\lfloor \frac{m}{p}\rfloor)}}\)​)作为主枚举,将对于质数的枚举转化为可以通过整除分块的前缀和优化的形式

将上式的 \(t\) 转变为原来的 \(p*t\),即直接枚举 \(k\)

可得 \(\large{ans=\sum_{t=1}^{min(n,m)}\lfloor \frac{n}{t}\rfloor \lfloor \frac{m}{t}\rfloor\sum_{p|t,(p\in Prime)}\mu(\frac{t}{p})}\)

// 记录答案的代码(未优化,辅助理解上式)
for(int t = 1; t <= min(n, m); t++){
	for(int p = 2; p <= t; p++){
		if(v[p] || t%p) continue;
		ans += (n/t)*(m/t)*miu[t/p];
	}
}

在计算 \(\mu\) 时,我们进行一个小的前缀和,即可通过整除分块优化求解

void init(){
	ll maxn = N-5;
	for(ll i = 1; i <= maxn; i++) miu[i] = 1;
	for(ll i = 2; i <= maxn; i++){
		if(v[i]) continue;
		p.pb(i);
		miu[i] = -1;
		for(ll j = 2; j*i <= maxn; j++){
			v[j*i] = 1;
			if(j%i == 0) miu[j*i] = 0;
			else miu[j*i] *= -1;
		}
	}
	for(auto i : p) // 此处前缀和直接对于每个数x累加所有的miu[x/p],并记录在s[x]
		for(ll j = 1; j*i <= maxn; j++)
			s[j*i] += miu[j];
	for(ll i = 1; i <= maxn; i++) sum[i] = sum[i-1]+s[i];
}
void solve(){
	n = read(), m = read(), ans = 0;
	for(ll l = 1, r; l <= min(n, m); l = r+1){
		r = min(n/(n/l), m/(m/l));
		ans += (n/l)*(m/l)*(sum[r]-sum[l-1]);
	}
	write(ans);
}

更多题目(待补):

P1829 [国家集训队] Crash的数字表格 / JZPTAB

莫比乌斯反演(函数)练习题单

Peter的莫比乌斯反演与各种筛法题单

本文大多摘抄自博客园与csdn上的众多文章,更多的起到个人学习与复习作用,也希望能对更多人学习起到帮助。

2025.7.4

posted @ 2025-07-03 21:53  Hirasawayuiii  阅读(16)  评论(0)    收藏  举报