莫比乌斯反演与狄利克雷卷积

Part0:符号约定

\([p]\):艾弗森记号.对于命题\(p\),当\(p\)成立时,\([p]\)\(1\),否则为\(0\).

\(a|b\):\(b\)\(a\)整除.即\(\exist k\in\Z\)使得\(b=ka\).

\(a\perp b\):\(a\)\(b\)互质,即\(\gcd(a,b)=1\).特殊地,\(1\perp 1\)也成立.

本文中的函数,未经特殊说明,均指数论函数,即定义在正整数集\(\N^+\)上的一类函数.本文中\(n,m,t,i,j,k\)默认表示某个正整数,\(p\)默认为某个素数.

Part1:整除分块

我们的目标是求数论函数

\[S(n)=\sum_{i=1}^n\left\lfloor\frac ni\right\rfloor \]

的值.显然,我们可以在\(O(n)\)时间内朴素地求出该函数的值.但是,画出\(\left\lfloor\frac ni\right\rfloor\)的图像可知,该函数有许多值是一样的,并且呈块状分布.并且更一般地,每一个块的最后一个数就是\(\left\lfloor n/(\left\lfloor \frac ni\right\rfloor)\right\rfloor\)

KHwsvF.md.png

于是,我们就有一种\(O(\sqrt n)\)的算法:

\(\text{CALC_DIVIDE_SUM}(n):\)
\(res\leftarrow 0\)
\(l\leftarrow 1\)
\(r\leftarrow 0\)
\(\mathbf{while}\ l\le n:\)
\(\quad r\leftarrow \left\lfloor n/(\left\lfloor \frac nl\right\rfloor)\right\rfloor\)
\(\quad res\leftarrow res+(r-l+1)\cdot \left\lfloor\frac nl\right\rfloor\left\lfloor\frac ml\right\rfloor\)
\(\quad l\leftarrow r+1\)
\(\mathbf{return}\ res\)

C++实现如下:

inline int divide_sum(int n)
{
    for(int l=1,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans+=(r-l+1)*(n/l);
    }
    return ans;
}

当然,我们有时候是求函数的和,这时候就要将r-l+1替换为函数在这一段区间上的和.

如果我们要求

\[S(n,m)=\sum_{i=1}^{\min(n,m)}\left\lfloor\frac ni\right\rfloor\left\lfloor\frac mi\right\rfloor \]

也可设计出以下\(O(\sqrt n+\sqrt m)\)的算法:

\(\text{CALC_DIVIDE_SUM2}(n,m):\)
\(res\leftarrow 0\)
\(l\leftarrow 1\)
\(r\leftarrow 0\)
\(\mathbf{while}\ l\le \min(n,m):\)
\(\quad r\leftarrow \min(\left\lfloor n/(\left\lfloor \frac nl\right\rfloor)\right\rfloor,\left\lfloor m/(\left\lfloor \frac ml\right\rfloor)\right\rfloor)\)
\(\quad res\leftarrow res+(r-l+1)\cdot \left\lfloor\frac nl\right\rfloor\left\lfloor\frac ml\right\rfloor\)
\(\quad l\leftarrow r+1\)
\(\mathbf{return}\ res\)

C++实现如下:

inline int divide_sum(int n,int m)
{
    for(int l=1,r;l<=std::min(n,m);l=r+1)
    {
        r=std::min(n/(n/l),m/(m/l));
        ans+=(r-l+1)*(n/l)*(m/l);
    }
    return ans;
}

Part2:狄利克雷卷积

定义两个数论函数\(f,g\)狄利克雷卷积(Dirichlet convolution)为:

\[\begin{align} (f*g)(n)&=\sum_{i|n}f(i)g\left(\frac ni\right)\\ &=\sum_{ij=n}f(i)g(j) \end{align} \]

狄氏卷积有以下性质:

(交换律)\(1.f*g=g*f\);

(结合律)\(2.f*g*h=(f*g)*h=f*(g*h)\),这是因为

\[\sum_{ijk=n}f(i)g(j)h(k)=\sum_{(ij)k=n}(f(i)g(j))h(k)=\sum_{i(jk)=n}f(i)(g(j)h(k)). \]

(分配律)\(3.(f+g)*h=f*h+g*h\);

(数乘律)\(4.(mf)*g=f*(mg)=m(f*g)\);

(单位元)\(5.e*f=f\),其中

\[e(n)=[n=1]=\begin{cases} 1,n=1,\\ 0,n>1; \end{cases} \]

(逆元)\(6.\)对于每个\(f(1)\ne0\)的函数\(f\),都存在一个函数\(g\)使得\(f*g=e\),记作\(g=f^{-1}\).

从上述结论可以看出,所有\(f(1)\ne0\)的函数对狄氏卷积构成一个群.

那么,如何求出一个函数的逆呢?

事实上,有

\[f^{-1}(n)=g(n)=\frac1{f(1)}\left([n=1]-\sum_{i|n,i\ne 1}f(i)g\left(\frac ni\right)\right) \]

因为

\[\begin{align} (f*g)(n)&=\sum_{i|n}f(i)g\left(\frac ni\right)\\ &=f(1)g(n)+\sum_{i|n,i\ne 1}f(i)g\left(\frac ni\right)\\ &=[n=1]. \end{align} \]

Part3:积性函数

若一个数论函数\(f\)满足:当\(n\perp m\)时,有\(f(nm)=f(n)f(m)\),则称之为积性函数(multiplicative function).

一些常见的积性函数有:\(e(n)=[n=1];\text{id}(n)=n;\text{id}^k(n)=n^k;1(n)=\text{id}^0(n)=1\).事实上,这些函数是完全积性函数(completelty multiplicative function),即不论\(n,m\)是否互质,都有\(f(nm)=f(n)f(m)\).

另外,\(n\)的因数个数\(\sigma_0(n)\)和欧拉函数\(\varphi(n)\)(\(1,2,\dots,n\)中与\(n\)互质的数的个数)也是积性函数.证明如下:

引理 如果\(n\perp m\),我们发现每个\(nm\)的约数\(t\)都可以分解成一个\(n\)的约数\(\gcd(n,t)\)和一个\(m\)的约数\(\gcd(m,t)\)的积,并且这种分解是一一对应的.

这是因为\(n\perp m,t|nm\Rightarrow t=\gcd(t,nm)=\gcd(t,n)\gcd(t,m)\),而且\(a|n,b|m\Rightarrow ab|nm\),并且,\(a|n,b|n\Rightarrow\gcd(ab,n)=a\).

于是\(\sigma_0(nm)=\sigma_0(n)\sigma_0(m)\).

同样的,\(t\perp nm\Leftrightarrow t\perp n,t\perp m\Leftrightarrow(t\bmod n)\perp n,(t\bmod m)\perp m\),所以每个\(1,2,\dots,nm\)之间的与\(nm\)互质的数\(t\)都可以对应到一个\(1,2,\dots,n\)的与\(n\)互质的数\(t\bmod n\)和一个\(1,2,\dots,m\)的与\(m\)互质的数\(t\bmod m\).

并且根据中国剩余定理,这种对应是一一对应的(即已知\(a\perp n,b\perp m\)后可以唯一确定一个\(1,2,\dots,nm\)之间的\(t\)使得\(t\bmod n=a, t\bmod m=b\),且\(t\perp nm\)).因此\(\varphi(nm)=\varphi(n)\varphi(m)\).

下面我们来证明两个结论:

\(1.\)两个积性函数的狄氏卷积是积性函数.

由于上面的引理,又因为\(n\perp m,a|n,b|m\Rightarrow a\perp b\),于是若\(n\perp m\),则

\[\begin{align} h(nm)=(f*g)(nm)&=\sum_{d|nm}f(d)g\left(\frac{nm}d\right)\\ &=\sum_{a|n,b|m}f(ab)g\left(\frac{nm}{ab}\right)\\ &=\sum_{a|n,b|m}f(a)f(b)g\left(\frac na\right)g\left(\frac mb\right)\\ &=\left(\sum_{a|n}f(a)g\left(\frac na\right)\right)\left(\sum_{b|m}f(b)g\left(\frac mb\right)\right)\\ &=h(n)h(m). \end{align} \]

\(2.\)积性函数的逆是积性函数.

\(nm\)的大小运用数学归纳法.设\(f^{-1}=g\),则

\(1.\)\(nm=1\)时,\(g(1)=1\),结论成立;

\(2.\)假设\(nm>1\),当\(n'm'<nm\)时有\(g(n'm')=g(n')g(m')\),

\[\begin{align} g(nm)&=-\sum_{d|nm,d\ne 1}f(d)g\left(\frac{nm}d\right)\\ &=-\sum_{a|n,b|m,ab\ne 1}f(ab)g\left(\frac{nm}{ab}\right)\\ &=-\sum_{a|n,b|m,ab\ne 1}f(a)f(b)g\left(\frac na\right)g\left(\frac mb\right)\\ &=f(1)f(1)g(n)g(m)-\sum_{a|n,b|m}f(a)f(b)g\left(\frac na\right)g\left(\frac mb\right)\\ &=g(n)g(m)-\left(\sum_{a|n}f(a)g\left(\frac na\right)\right)\left(\sum_{b|m}f(b)g\left(\frac mb\right)\right)\\ &=g(n)g(m)-e(n)e(m)\\ &=g(n)g(m) \end{align} \]

Part4:积性函数的线性筛

根据算数基本定理,由于每个正整数\(n\)可以写成惟一的分解形式\(n=\prod\limits_{i=1}^{m}p_i^{\alpha_i}\),所以

\[f(n)=\prod_{i=1}^mf(p_i^{\alpha_i}) \]

所以,一个积性函数在素数幂处的取值决定了整个积性函数.并且,由于在线性筛素数时我们可以顺便求出每个数的最小质因数\(p_1\)以及最小质因数的次数\(\alpha_1\)以及\(n/p_1^{\alpha_1}\),就可以利用递推式\(f_n=f(p_1^{\alpha_1})f(n/p_1^{\alpha_1})\)直接计算\(f\)了.

另外,由于\(\sigma_0\)\(\varphi\)在素数幂处的取值容易得到:\(\sigma_0(p^k)=k+1,\varphi(p^k)=p^{k-1}(p-1)\),所以

\[\sigma_0(n)=\prod_{i=1}^m(\alpha_i+1),\\ \varphi(n)=\prod_{i=1}^mp_i^{\alpha_i-1}(p_i-1)=n\prod_{i=1}^m\left(1-\frac1{p_i}\right) \]

\(\varphi*1\)也是积性函数,又\((\varphi*1)(p^k)=p^k\),故有\(\text{id}=\varphi*1\).

Part5:莫比乌斯函数与莫比乌斯反演

我们定义\(1\)的逆是\(\mu\),称为莫比乌斯函数(Mobius function).这样的话,若\(g=f*1\),则就有\(f=g*\mu\),更一般地,

\[g(n)=\sum_{d|n}f(d)\Leftrightarrow f(n)=\sum_{d|n}\mu\left(\frac nd\right)g(d) \]

或等价地,

\[g(n)=\sum_{n|m}f(m)\Leftrightarrow f(n)=\sum_{n|m}\mu\left(\frac mn\right)g(m) \]

上述公式称为莫比乌斯反演公式(Mobius inversion formula).或者类似地,我们可以发现\(\text{id}^k\)的逆是\(f(n)=\mu(n)n^k\),于是若

\[g(n)=\sum_{d|n}\left(\frac nd\right)^kf(d) \]

就有

\[f(n)=\sum_{d|n}\mu\left(\frac nd\right)\left(\frac nd\right)^kg(d) \]

比如,可得\(\varphi=\mu*\text{id}\),即

\[\varphi(n)=\sum_{d|n}\mu\left(\frac nd\right)d \]

那么,如何求\(\mu\)呢?

由于\(1\)是积性的,而\(\mu\)\(1\)的逆,所以\(\mu\)也是积性的.容易计算出:

\[\mu(p^k)=\begin{cases} 1,k=0,\\ -1,k=1,\\ 0,k>1 \end{cases} \]

于是,

\[\mu(n)= \begin{cases} (-1)^m,n=p_1p_2\dots p_m,p_i\ne p_j,i,j=1,2,\dots,m,\\ 0,\text{otherwise} \end{cases}. \]

莫比乌斯函数有以下性质:

\(1.\)对于任意的正整数\(n\),有

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

\(2.\)对于任意的正整数\(n\),有

\[\sum_{d|n}\frac{\mu(d)}{d}=\frac{\varphi(n)}{n} \]

运用上面的性质\(1\),我们容易得出\(\mu\)的线性筛代码:

\(\text{LINEAR_SIEVE_MU}(n):\)
\(\mu\leftarrow\ new\ array\ filled\ with\ 0\)
\(\mathbf{for}\ i\leftarrow 1\ \mathbf{to}\ n:\)
\(\quad tar\leftarrow [i=1]//tar\text{ is the sum of Mobius functions so far}\)
\(\quad \delta\leftarrow tar-\mu[i]//\delta\text{ is the differences between the functions and the sum}\)
\(\quad \mu[i]\leftarrow \delta\)
\(\quad j\leftarrow 2i\)
\(\quad \mathbf{while}\ j\le n:\)
\(\quad\quad mu[j]\leftarrow mu[j]+\delta\)
\(\quad\quad j\leftarrow j+i\)
\(\mathbf{return}\ \mu\)

C++实现如下:

void sieve_mu(int n,int mu[]) //mu是储存结果的数组
{
	for(int i=1;i<=n;++i)
	{
		int tar=(i==1?1:0);
		int delta=tar-mu[i];
		mu[i]=delta;
				
		for(int j=2*i;j<=n;j+=i)
			mu[j]+=delta;
	}
}

我们也可以在筛素数的同时筛出\(\mu\):

\(\text{LINEAR_SIEVE_PRIME_AND_MU}(n):\)
\(\mu,p\leftarrow\ new\ array\ filled\ with\ 0\)
\(vis\ new\ array\ filled\ with\ \mathbf{FALSE}//vis\text{ is used to label numbers whether has divisors or not}\)
\(\mu[1]\leftarrow 1\)
\(\mathbf{for}\ i\leftarrow 2\ \mathbf{to}\ n:\)
\(\quad \mathbf{if}\ vis[i]=\mathbf{FALSE}:\)
\(\quad\quad p.append(i)\)
\(\quad\quad mu[i]\leftarrow-1\)
\(\quad \mathbf{for}\ each\ prime\ p_0\ \mathbf{in}\ p:\)
\(\quad\quad vis[p_0\cdot i]\leftarrow \mathbf{TRUE}\)
\(\quad\quad \mathbf{if}\ p|i:\)
\(\quad\quad\quad \mathbf{break}\)
\(\quad\quad \mathbf{else}:\)
\(\quad\quad\quad \mu[i\cdot p_0]\leftarrow-\mu[i]\)
\(\mathbf{return}\ \mu,p\)

C++实现如下:

void sieve_mu(int n,int mu[],int p[],int vis[],int& cnt)
{
    memset(vis,0,sizeof(vis));
	mu[1]=1;
	cnt=0;

	for(int i=2;i<=n;++i)
	{
		if(!vis[i])
		{
			p[++cnt]=i;
			mu[i]=-1;
		}

		for(int j=1;j<=cnt&&p[j]*i<=n;++j)
		{
			vis[p[j]*i]=1;

			if(i%p[j]==0)
				break;
			else
				mu[i*p[j]]=-mu[i];
		}
	}
}

Part6:简单例题

LG P2257 YYY的GCD

对于\(n,m\),我们有\(d|\gcd(a,b)\Leftrightarrow d|a,d|b\).于是,对一个关于\(\gcd(a,b)\)的函数\(f(\gcd(a,b))\),如果有\(f(n)=\sum\limits_{d|n}g(d)\)的话,就可以写成\(\sum\limits_{d|a,d|b}g(d)\)了.

考虑令\(f(n)=[n是素数]\).我们要找到一个\(g\)使得\(f=1*g\),那么\(g=\mu*f\),

\[g(n)=\sum_{d|n}\mu\left(\frac nd\right)[d是素数]=\sum_{p|n}\mu\left(\frac np\right) \]

于是我们可以这样求出\(g\):

\(\text{SIEVE_G}(n):\)
\(g\leftarrow\ new\ array\ filled\ with\ 0\)
\(\mu,p\leftarrow \text{LINEAR_SIEVE_PRIME_AND_MU}(n)\)
\(\mathbf{for}\ each\ p_0\ \mathbf{in}\ p:\)
\(\quad i\leftarrow 1\)
\(\quad \mathbf{while}\ i\cdot p_0\le n:\)
\(\quad\quad g[i\cdot p]\leftarrow g[i\cdot p]+\mu[i]\)
\(\mathbf{return}\ g\)

复杂度为\(O(\sum\limits_{p\le n}(n/p))=O(n\log\log n)\).

我们要求的是

\[\begin{align} &\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}g(d)\\ &=\sum_{d=1}^{\min(n,m)}g(d)\sum_{i=1}^n\sum_{j=1}^m[d|i][d|j]\\ &=\sum_{d=1}^{\min(n,m)}g(d)\left\lfloor\frac nd\right\rfloor\left\lfloor\frac md\right\rfloor \end{align} \]

先预处理\(g\)的前缀和,然后就可以用整除分块之后\(O(\sqrt n+\sqrt m)\)回答每个询问.C++实现如下:

const int Maxn=1e7+5,MaxLogn=15;
int n,m,cnt,p[Maxn/MaxLogn],mu[Maxn],g[Maxn];
bool vis[Maxn];

void sieve()
{
	mu[1]=vis[1]=1;
	for(int i=2;i<Maxn;++i)
	{
		if(!vis[i])
		{
			p[++cnt]=i;
			mu[i]=-1;
			g[i]=1;
		}
		
		for(int j=1;j<=cnt&&i*p[j]<Maxn;++j)
		{
			int x=i*p[j];
			vis[x]=1;
			
			if(i%p[j]==0)
			{
				g[x]=mu[i];
				mu[x]=0;
				break;
			}
			else
			{
				g[x]=-g[i]+mu[i];
				mu[x]=-mu[i];
			}
		}
		
		g[i]+=g[i-1];
	}
}

int main()
{
	sieve();
	int T;
	scanf("%d",&T);
	
	for(;T--;)
	{
		scanf("%d%d",&n,&m);
		long long ans=0;
		
		if(n>m)
			swap(n,m);
			
		for(int l=1,r;l<=n;l=r+1)
		{
			r=min(n/(n/l),m/(m/l));
			ans+=1LL*(g[r]-g[l-1])*(n/l)*(m/l);
		}
		
		printf("%lld\n",ans);
	}
}

本文完

posted @ 2019-11-01 20:09  Anverking  阅读(344)  评论(0编辑  收藏  举报