ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于莫比乌斯反演

2021-12-14 07:00:54  阅读:217  来源: 互联网

标签:lfloor ab gcd 乌斯 sum rfloor mu 反演 莫比


狄利克雷卷积与数论函数:

狄利克雷卷积写作:

\[f(x)*g(x)=(f*g)(x) \]

定义:

\[(f*g)(x)=\sum_{d|n}^nf(d)*g(n/d) \]

也可以写作:

\[(f*g)(x)=\sum_{x*y=n}^nf(x)*g(y) \]

狄利克雷卷积满足交换律与结合律:

\[\begin{cases} (f*g)(n)=\sum_{x*y=n}^n\limits f(x)*g(y)=\sum_{x*y=n}^n\limits g(x)*f(y)=(g*f)(n)\\ \\ ((f*g)*h)(n)=\sum_{x*y*z=n}^n\limits f(x)*g(y)*h(z)=(f*(g*h))(n)\\ \end{cases} \]

狄利克雷卷积是一个对称的结构

一些简单的数论函数:

定义:积性函数:

对于一个函数 \(F\) , 如果 \(gcd(a,b)=1\) 时有\(F(ab)=F(a)F(b)\),则该函数是积性函数。

定义:完全积性函数:

对于任意的整数 \(a\) 和 \(b\) 有 \(F(ab)=F(a)F(b)\)

很明显,完全积性函数∈积性函数。

一些常见的积性函数:

恒等函数,无论 \(n\) 是啥,它永远等于1:

\[I(n)=1 \]

元函数,当 \(n=1\) 时,函数值为 \(1\),否则为 \(0\):

\[e(n)=[n==1] \]

单位函数:

\[id(n)=n \]

幂函数,单位函数是它的特殊情况:

\[id^k(n)=n^k \]

欧拉函数,小于n的整数中,与n互质的数的个数:

\[\varphi(n)=\sum_{i=1}^{n-1}[gcd(i,n)==1] \]

以及下文要用到的莫比乌斯函数 \(\mu(n)\)

积性函数的一些性质:

\[\begin{cases} F(1)=F(1)F(1)→ F(1)=1\\ \\ F(x)=F(p_1^{k1})F(p_2^{k2})...F(p_m^{km})\\ \end{cases}\]


积性函数的逆也是积性函数:

首先,定义函数在狄利克雷卷积意义下的逆:

考虑:

\[(F*e)(n)=\sum_{d|n}^n[n/d==1]*F(d) \]

即:

\[(F*e)(n)=\sum_{d|n}^n[d==n]*F(d) \]

即:

\[F*e=F \]

那么,如果 \(G*F=e\) ,我们就说 \(F\) 与 \(G\) 互逆

\[G*F=e ⇔ G=F^{-1} \]

下证:

\[\begin{cases} F(ab)=F(a)F(b)\\ \\ gcd(a,b)==1\\ \end{cases} → F^{-1}(ab)=F^{-1}(a)F^{-1}(b)\]

因为:

\[e=\sum_{d|n}^nF(d)F^{-1}(n/d) \]

考虑归纳证明:

当 \(a=1\) 或 \(b=1\) 时:

若 \(a,b\) 均等于 \(1\) ,\(e(1)=F(1)*F^{-1}(1)=1\)

而 \(F(1)=1\) ,因此 \(F^{-1}(1)=1\)

当 \(a,b>1\) 时:

设,对于 \(\forall a'<a,b'<b\),都有 \(F^{-1}(a'b')=F^{-1}(a')F^{-1}(b')\)

下证 \(F^{-1}(ab)=F^{-1}(a)F^{-1}(b)\)

显然,有:

\[\sum_{d|n,d!=1}^nF(d)F^{-1}(n/d)+F(1)F^{-1}(n)=\sum_{d|n}^nF(d)F^{-1}(n/d) \]

即:

\[\sum_{d|n}^nF(d)F^{-1}(n/d)-\sum_{d|n,d!=1}^nF(d)F^{-1}(n/d)=F^{-1}(n) \]

有:

\[F^{-1}(ab)=\sum_{d|ab}^{ab}F(d)F^{-1}(ab/d)-\sum_{d|ab,d!=1}^{ab}F(d)F^{-1}(ab/d) \]

\[F^{-1}(ab)=e(ab)-\sum_{d|ab,d!=1}^{ab}F(d)F^{-1}(ab/d) \]

\[F^{-1}(ab)=0-\sum_{d|ab,d!=1}^{ab}F(d)F^{-1}(ab/d) \]

\[=-\sum_{d|ab,d!=1}^{ab}F(d)F^{-1}(ab/d) \]

\[=-\sum_{i|a}^{a}\sum_{j|b,ij!=1}^{b}F(ij)F^{-1}(ab/ij) \]

\[=-\sum_{i|a}^{a}\sum_{j|b,ij!=1}^{b}F(i)F^{-1}(j)F^{-1}(a/i)F(b/j) \]

\[=-\sum_{i|a}^{a}F(i)F^{-1}(a/i)\sum_{j|b,ij!=1}^{b}F^{-1}(j)F(b/j) \]

\[=F(1)F^{-1}(a)F^{-1}(1)F(b)-\sum_{i|a}^{a}F(i)F^{-1}(a/i)\sum_{j|b}^{b}F^{-1}(j)F(b/j) \]

\[=F^{-1}(a)F(b)-e(a)*e(b) \]

\[=F^{-1}(a)F(b) \]

证毕


莫比乌斯反演:

设:

\[F(n)=\sum_{d|n}^nf(d) \]

显然:

\[F(n)=\sum_{d|n}^nf(d)*1 \]

即:

\[F=I*f \]

那么:

\[f=I^{-1}*F \]

现在只需要求 \(I^{-1}\) 即可通过 \(F\) 反演出 \(f\) 。

令 \(\mu=I^{-1}\),显然 \(\mu\) 是积性函数。

先从 \(\mu(p^k)\) 入手:

当 \(k=0\) 时:

\[e(1)=I(1)*\mu(1)=1 \]

因此 \(\mu(1)=1\)

\(k=1\) 时:

\[e(p)=I(1)*\mu(p)+I(p)*\mu(1)=0 \]

\[\mu(p)+\mu(1)=0 \]

\[\mu(p)=-1 \]

\(k=2\) 时:

\[e(p^2)=I(1)*\mu(p^2)+I(p)*\mu(p)+I(p^2)*\mu(1)=0 \]

\[\mu(p^2)+\mu(p)+\mu(1)=0 \]

\[\mu(p^2)+0=0 \]

\[\mu(p^2)=0 \]

\(k>2\) 时,数学归纳法可证 \(\mu(p^k)=0\)

因此,若:

\[n=pri_1^{k_1}*pri_2^{k_2}*... \]

则:

\[\mu(n)=\begin{cases} 0\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ \exists\ k_i>1]\\ (-1)^{\sum k}\ \ \ \ \ [\ \forall\ k_i<=1]\\ \end{cases}\]

这就有了莫反的第一种形式:

\[F(n)=\sum_{d|n}^nf(d) ⟺ f(n)=\sum_{d|n}^n\mu(d)F(n/d)\ \ \ (1) \]

也是最常用的形式。

还有倍数形式:

\[F(n)=\sum_{n|d}^nf(d) ⟺ f(n)=\sum_{n|d}^n\mu(d)F(d/n)\ \ \ (2) \]

可以左式代入右式中证明,更简单的方法是像二项式反演那样,直接把转移写成矩乘的形式,转置一下即可。

以上两个式子由于转移方向单一,而且复杂度没什么优化,所以一般可以直接一层容斥解决,不需要莫反

更有用的是嵌入式莫反:

因为:

\[I*\mu=e \]

所以:

\[\sum_{d|n}^n\mu(d)=[n=1] \]

由于:

\[[n|m][m/n=1]=[n=m] \]

所以:

\[[n|m]\sum_{d|m/n}^{m/n}\mu(d)=[n=m] \]


莫比乌斯反演与整除分块:

  • (1)求:

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1] \]

我们使用嵌入式反演,有:

\[\sum_{d|n}^n\mu(d)=[n=1] \]

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1]=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|gcd(i,j)}^{gcd(i,j)}\mu(d) \]

由于:

\[[d|gcd(i,j)]=[d|i][d|j] \]

因此:

\[\sum_{i=1}^n\sum_{j=1}^m[gcd=1]=\sum_{d}^{min(n,m)}\mu(d)\sum_{d|i}^n\sum_{d|j}^m1 \]

\[\sum_{i=1}^n\sum_{j=1}^m[gcd=1]=\sum_{d}^{min(n,m)}\mu(d) \lfloor n/d \rfloor \lfloor m/d \rfloor \]

预处理前缀和,整除分块即可在 \(O(\sqrt n)\) 时间内求解

  • (2)求:

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k] \]

我们使用嵌入式反演,有:

\[[n|k]\sum_{d|k/n}^{k/n}\mu(d)=[n=k] \]

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k]=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)|k]\sum_{d|k/gcd(i,j)}^{k/gcd(i,j)}\mu(d) \]

因此:

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k]=\sum_{d=1}^{min(n,m)}\mu(d)\sum_{d|i}^{n/k}\sum_{d|j}^{m/k}1 \]

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k]=\sum_{d=1}^{min(n,m)}\mu(d) \lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor \]

  • (3)求:

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)\in prime] \]

即:

\[\sum_{k \in prime}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k] \]

\[=\sum_{k \in prime}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)|k]\sum_{d|k/gcd(i,j)}^{k/gcd(i,j)}\mu(d) \]

\[=\sum_{k \in prime}^{min(n,m)}\sum_{d=1}^{min(n/k,m/k)}\mu(d)\sum_{d|i}^{n/k}\sum_{d|j}^{m/k}1 \]

\[=\sum_{k \in prime}^{min(n,m)}\sum_{d=1}^{min(n/k,m/k)}\mu(d)\sum_{kd|i}^{n}\sum_{kd|j}^{m}1 \]

另 \(d=kd\) ,枚举新的 \(d\):

\[\sum_{k \in prime}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k]=\sum_{d=1}^{min(n,m)}\sum_{k \in prime,k|d}^{min(n,m)}\mu(d/k)\sum_{d|i}^{n}\sum_{d|j}^{m}1 \]

\[=\sum_{d=1}^{min(n,m)}\sum_{k \in prime,k|d}^{min(n,m)}\mu(d/k) \lfloor n/d \rfloor \lfloor m/d \rfloor \]

\[=\sum_{d=1}^{min(n,m)} \lfloor n/d \rfloor \lfloor m/d \rfloor \sum_{k \in prime,k|d}^{min(n,m)}\mu(d/k) \]

将预处理 \(\mu(d)\) 的前缀和改为预处理 \(\sum_{k \in prime,k|d}^{min(n,m)}\limits \mu(d/k)\) 即可。

  • (4)求:

\[\prod_{i=1}^n\prod_{j=1}^n\frac{lcm(i,j)}{gcd(i,j)} \]

显然:

\[\prod_{i=1}^n\prod_{j=1}^n\frac{lcm(i,j)}{gcd(i,j)}=\prod_{i=1}^n\prod_{j=1}^n\frac{i*j}{gcd(i,j)^2} \]

\[=(\prod_{i=1}^n\prod_{j=1}^ni*j)*(\prod_{i=1}^n\prod_{j=1}^ngcd(i,j))^{-2} \]

\[=(\prod_{i=1}^n(i^n*n!))*(\prod_{k=1}^{n}k^{-2*(\sum_{i=1}^{n/k}\limits \sum_{j=1}^{n/k}\limits [gcd(i,j)=k])}) \]

\[=(n!)^{2n}*(\prod_{k=1}^{n}k^{-2*(\sum_{d=1}^{n/k}\limits\mu(d) \lfloor \frac n{kd} \rfloor^2)}) \]

如果对 \(\lfloor \frac n{kd} \rfloor\) 整除分块,分别对每个 \(d\) 求出对应的 \(\sum_{d=1}^{n/k}\limits\mu(d) \lfloor \frac n{kd} \rfloor^2)\),时间复杂度就是 \(O(n \sqrt n)\) 的。

我们可以直接对 \(n/k\) 整除分块,求出 \(\prod_{k=1}^{n}k^{-2*(\sum_{d=1}^{n/k}\limits\mu(d) \lfloor \frac n{kd} \rfloor^2)}\) ,时间复杂度就约为 \(O(\sqrt n*\sqrt n)=O(n)\)

  • (5)求:

\[\sum_{i=1}^n \sum_{j=1}^md(ij) \]

有等式:

\[d(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)==1] \]

对于每一个质因数讨论,令 \(k_x\) 表示最大的 \(prime^k|x\)。

用 \(d\) 表示所枚举的约数,设 \(k_i>k_j\)。

那么若\(k_y=0\),则 \(k_d=k_x\) ,若 \(k_x=0\),则 \(k_d=k_i+k_y\)。

显然这样可以表示出所有约数,等式成立。

\[\sum_{i=1}^n \sum_{j=1}^md(ij)=\sum_{i=1}^n \sum_{j=1}^m\sum_{x|i}\sum_{y|j}[gcd(x,y)==1] \]

\[=\sum_{i=1}^n \sum_{j=1}^m\sum_{x|i}\sum_{y|j}\sum_{d|gcd(x,y)}\mu(d) \]

\[=\sum_{x=1}^n \sum_{y=1}^m\lfloor \frac {n}{x} \rfloor\lfloor \frac {m}{y} \rfloor \sum_{d|gcd(x,y)}\mu(d) \]

\[=\sum_{i=1}^n \sum_{j=1}^m\lfloor \frac {n}{i} \rfloor\lfloor \frac {m}{j} \rfloor \sum_{d|gcd(x,y)}\mu(d) \]

\[=\sum_d^{min(n,m)}\mu(d)\sum_{i=1}^{\lfloor \frac n d\rfloor }\sum_{j=1}^{\lfloor \frac m d \rfloor}\lfloor \frac {n}{id} \rfloor\lfloor \frac {m}{jd} \rfloor \]

\[=\sum_d^{min(n,m)}\mu(d)\sum_{i=1}^{\lfloor \frac n d\rfloor }\lfloor \frac {n}{id} \rfloor\sum_{j=1}^{\lfloor \frac m d \rfloor}\lfloor \frac {m}{jd} \rfloor \]

整除分块即可

[SDOI2008] 仪仗队

#include<bits/stdc++.h>
using namespace std;
int q;
long long mu[50005];
int pri[50005],top;
bool vis[50005];
inline void init(){
	mu[1]=1;
	for(int i=2;i<=5e4;i++){
		if(!vis[i])pri[++top]=i,mu[i]=-1;
		for(int j=1;j<=top&&pri[j]*i<=5e4;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)break;
			mu[i*pri[j]]=-mu[i];
		}
	}for(int i=1;i<=5e4;i++)mu[i]+=mu[i-1];
}
inline long long solve(int n,int m){
	long long res=0;
	for(int l=1,r=0;l<=n&&l<=m;l=r+1){
		r=min(n/(n/l),m/(m/l));
		res+=1ll*(mu[r]-mu[l-1])*(n/l)*(m/l);
	}return res;
}
int main(){
	init();
	scanf("%d",&q);if(q==1){puts("0");return 0;}
	printf("%lld",solve(q-1,q-1)+2);
//	scanf("%d",&q);
//	while(q--){
//		int n,m;
//		scanf("%d%d",&n,&m);
//	}

	return 0;
}



[POI2007]ZAP-Queries

#include<bits/stdc++.h>
using namespace std;
int q;
long long mu[50005];
int pri[50005],top;
bool vis[50005];
inline void init(){
	mu[1]=1;
	for(int i=2;i<=5e4;i++){
		if(!vis[i])pri[++top]=i,mu[i]=-1;
		for(int j=1;j<=top&&pri[j]*i<=5e4;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)break;
			mu[i*pri[j]]=-mu[i];
		}
	}for(int i=1;i<=5e4;i++)mu[i]+=mu[i-1];
}
inline long long solve(int n,int m,int d){
	long long res=0;
	for(int l=1,r=0;l<=n&&l<=m;l=r+1){
		r=min(n/(n/l),m/(m/l));
		res+=1ll*(mu[r]-mu[l-1])*(n/l/d)*(m/l/d);
	}return res;
}
int main(){
	init();
	scanf("%d",&q);
	while(q--){
		int n,m,d;
		scanf("%d%d%d",&n,&m,&d);
		printf("%lld\n",solve(n,m,d));
	}

	return 0;
}



YY的GCD

#include<bits/stdc++.h>
using namespace std;
int t,n,m;
long long mu[10000005],sum[10000005],f[10000005];
int pri[10000005],top;
bool vis[10000005];
inline void init(){
	mu[1]=1;
	for(int i=2;i<=1e7;i++){
		if(!vis[i])pri[top++]=i,mu[i]=-1;
		for(int j=0;j<top&&i*pri[j]<=1e7;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)break;
			mu[i*pri[j]]=-mu[i];
		}
	}
	for(int i=0;i<top;i++){
		for(int j=1;j*pri[i]<=1e7;j++)f[j*pri[i]]+=mu[j];
	}
	for(int i=1;i<=1e7;i++)sum[i]=sum[i-1]+f[i];
}
long long solve(){
	long long res=0;
	if(n>m)swap(n,m);
	for(int l=1,r=0;l<=n;l=r+1){
		r=min(n/(n/l),m/(m/l));
		res+=(sum[r]-sum[l-1])*(n/l)*(m/l);
	}return res;
}
int main(){
	init();//puts("000");
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		printf("%lld\n",solve());
	}

	return 0;
}


Product

#include<bits/stdc++.h>
using namespace std;
long long fac;
const long long md=104857601,phi=104857600;
int pri[1000005],top,mu[1000005];
bool vis[1000005];
inline void init(int n){
	mu[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i])pri[++top]=i,mu[i]=-1;
		for(int j=1;j<=top&&i*pri[j]<=n;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)break;
			mu[i*pri[j]]=-mu[i];
		}
	}
	fac=1;
	for(int i=1;i<=n;i++)fac=fac*i%md;
	for(int i=1;i<=n;i++)mu[i]+=mu[i-1];
}
inline long long pwr(long long x,long long y){
	long long res=1;
	while(y){
		if(y&1)res=res*x%md;
		x=x*x%md;y>>=1;
	}return res;
}
inline long long calc2(int n){
	long long res=0;
	for(int l=1,r=0;l<=n;l=r+1){
		r=n/(n/l);
		res=(res+1ll*(n/l)*(n/l)%phi*(mu[r]-mu[l-1]))%phi;
	}return (res+phi)%phi;
}
inline long long calc(int n){
	long long res=1;
	for(int l=1,r=0;l<=n;l=r+1){
		r=n/(n/l);fac=1;
		for(int i=l;i<=r;i++)fac=fac*i%md;
		res=res*pwr(fac*fac%md,calc2(n/l))%md;
	}return res;
}
int main(){
	int n;
	scanf("%d",&n);
	init(n);
	long long ans=pwr(fac*fac%md,n);
	printf("%lld",ans*pwr(calc(n),md-2)%md);

	return 0;
}



[SDOI2015]约数个数和

#include<bits/stdc++.h>
using namespace std;
int T;
long long mu[50005],s[50005];
int pri[50005],top;
bool vis[50005];
inline void init(){
	mu[1]=1;
	for(int i=2;i<=50000;i++){
		if(!vis[i])pri[++top]=i,mu[i]=-1;
		for(int j=1;j<=top&&i*pri[j]<=50000;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)continue;
			mu[i*pri[j]]=-mu[i];
		}mu[i]+=mu[i-1];
	}
	for(int i=1;i<=50000;i++){
		for(int l=1,r;l<=i;l=r+1){
			r=i/(i/l);
			s[i]+=i/l*(r-l+1);
		}
	}
}
inline long long solve(int n,int m){
	long long res=0;
	for(int l=1,r;l<=n&&l<=m;l=r+1){
		r=min(n/(n/l),m/(m/l));
		res+=(mu[r]-mu[l-1])*s[n/l]*s[m/l];
	}return res;
}
int main(){
	scanf("%d",&T);init();
	while(T--){
		int n,m;
		scanf("%d%d",&n,&m);
		printf("%lld\n",solve(n,m));
	}

	return 0;
}

标签:lfloor,ab,gcd,乌斯,sum,rfloor,mu,反演,莫比
来源: https://www.cnblogs.com/A-Quark/p/15686123.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有