莫比乌斯反演入门

##首先 … \ldots
我们来了解一下什么是莫比乌斯反演…

假设有两个函数 f ( i ) , g ( i ) f(i),g(i) f(i),g(i),并且 f ( N ) = ∑ i ∣ N g ( i ) \Large f(N)=\sum\limits_{i|N} g(i) f(N)=iNg(i)
也就是

  • f ( 1 ) = g ( 1 ) f(1)=g(1) f(1)=g(1)
  • f ( 2 ) = g ( 1 ) + g ( 2 ) f(2)=g(1)+g(2) f(2)=g(1)+g(2)
  • f ( 3 ) = g ( 1 ) + g ( 3 ) f(3)=g(1)+g(3) f(3)=g(1)+g(3)
  • f ( 4 ) = g ( 1 ) + g ( 2 ) + g ( 4 ) f(4)=g(1)+g(2)+g(4) f(4)=g(1)+g(2)+g(4)
  • f ( 5 ) = g ( 1 ) + g ( 5 ) f(5)=g(1)+g(5) f(5)=g(1)+g(5)
  • f ( 6 ) = g ( 1 ) + g ( 2 ) + g ( 3 ) + g ( 6 ) f(6)=g(1)+g(2)+g(3)+g(6) f(6)=g(1)+g(2)+g(3)+g(6)
    .
    .
    .

g ( i ) g(i) g(i) f f f的关系??
列一下

  • g ( 1 ) = f ( 1 ) g(1)=f(1) g(1)=f(1)
  • g ( 2 ) = − f ( 1 ) + f ( 2 ) g(2)=-f(1)+f(2) g(2)=f(1)+f(2)
  • g ( 3 ) = − f ( 1 ) + f ( 3 ) g(3)=-f(1)+f(3) g(3)=f(1)+f(3)
  • g ( 4 ) = − f ( 2 ) + f ( 4 ) g(4)=-f(2)+f(4) g(4)=f(2)+f(4)
  • g ( 5 ) = − f ( 1 ) + f ( 5 ) g(5)=-f(1)+f(5) g(5)=f(1)+f(5)
  • g ( 6 ) = − f ( 1 ) − f ( 2 ) − f ( 3 ) + f ( 6 ) g(6)=-f(1)-f(2)-f(3)+f(6) g(6)=f(1)f(2)f(3)+f(6)
    .
    .
    .

???
继续列下去(本人过于懒惰
似乎 g ( N ) = ∑ i ∣ N f ( i ) × ? ? \Large g(N)=\sum\limits_{i|N} f(i)\times ?? g(N)=iNf(i)×??
而且,这个 ? ? ?? ?? i i i没有关系,而是和 N i N\over i iN有关系

我们暂且将这个函数设为 μ ( N i ) \Large\mu({N\over i}) μ(iN)

并且这个函数的取值只有 − 1 , 0 , 1 -1,0,1 1,0,1

光这么看很难发现这个函数的规律,然而我们的大数学家莫比乌斯发现了(不然怎么叫莫比乌斯反演)
式子是这样的

\begin{equation}
\mu(N)=
\begin{cases}
1 & N=1\
(-1)^m & N=P_1P_2P_3\cdots P_m\
0 & N=P_1{k_1}P_2{k_2}P_3^{k_3}\cdots P_m^{k_m},k_1+k_2+k_3+\cdots +k_m>m\
\end{cases}
\end{equation}

P P P是互不相等的质数, k > 0 k>0 k>0

第二条就是至少有一个 k ≥ 2 k\geq2 k2

所以我们就有 g ( N ) = ∑ i ∣ N f ( i ) μ ( N i ) \Large g(N)=\sum\limits_{i|N} f(i)\mu({N\over i}) g(N)=iNf(i)μ(iN)

这条式子也可以这么写 g ( N ) = ∑ i ∣ N f ( N i ) μ ( i ) \Large g(N)=\sum\limits_{i|N} f({N\over i})\mu(i) g(N)=iNf(iN)μ(i)

这个函数就是莫比乌斯函数
##证明?
首先,莫比乌斯函数有几个性质。

  • 性质一 ∑ d ∣ n μ ( d ) = 0 ∣ n ∈ N ∗ , n > 1 \sum\limits_{d|n}\mu(d)=0|n\in N^*,n>1 dnμ(d)=0nN,n>1
    ∑ d ∣ n μ ( d ) = 1 ∣ n = 1 \sum\limits_{d|n}\mu(d)=1|n=1 dnμ(d)=1n=1
  • 性质二 莫比乌斯函数是积性函数 g c d ( p , q ) = 1 , μ ( p ) ∗ μ ( q ) = μ ( p ∗ q ) gcd(p,q)=1,\mu(p)*\mu(q)=\mu(p*q) gcd(p,q)=1,μ(p)μ(q)=μ(pq)

先证性质一。
n = 1 n=1 n=1时显然。

n > 1 n>1 n>1
n = P 1 k 1 P 2 k 2 P 3 k 3 ⋯ P m k m n=P_1^{k_1}P_2^{k_2}P_3^{k_3}\cdots P_m^{k_m} n=P1k1P2k2P3k3Pmkm d d d有其中一部分。
显然 d d d的每个质因子指数为1才有贡献,否则 μ ( d ) = 0 \mu(d)=0 μ(d)=0

那么设 d d d中有 r r r个质因子。
μ ( d ) = ( − 1 ) r \mu(d)=(-1)^r μ(d)=(1)r,这样的 d d d C m r C_{m}^{r} Cmr
所以 ∑ d ∣ n μ ( d ) = ∑ r = 0 m ( − 1 ) r C m r \sum\limits_{d|n}\mu(d)=\sum\limits_{r=0}^{m}(-1)^rC_{m}^{r} dnμ(d)=r=0m(1)rCmr

我们有二项式定理
∑ r = 0 m ( − 1 ) r C m r = ∑ r = 0 m C m r ( − 1 ) r 1 m − r = ( − 1 + 1 ) m = 0 \sum\limits_{r=0}^{m}(-1)^rC_{m}^{r}=\sum\limits_{r=0}^{m}C_{m}^{r}(-1)^r1^{m-r}=(-1+1)^m=0 r=0m(1)rCmr=r=0mCmr(1)r1mr=(1+1)m=0
得证!

性质二似乎比较显然,此处不准备证明。
然后我们来证明反演。

f ( N ) = ∑ d ∣ N g ( d ) ⇒ g ( N ) = ∑ d ∣ N f ( n d ) μ ( d ) = ∑ d ∣ N μ ( d ) ∑ i ∣ N d g ( i ) f(N)=\sum\limits_{d|N} g(d)\Rightarrow g(N)=\sum\limits_{d|N} f({n\over d})\mu(d)=\sum\limits_{d|N}\mu(d)\sum\limits_{i|{N\over d}}g(i) f(N)=dNg(d)g(N)=dNf(dn)μ(d)=dNμ(d)idNg(i)

然后我们运用一种叫交换主体的等价变换,就是将后面的 f ( i ) f(i) f(i)移到前面来,这个似乎只能靠感觉,多练练就熟了。
下面直接是交换后的,想想为什么?
= ∑ i ∣ N g ( i ) ∑ d ∣ N i μ ( d ) =\sum\limits_{i|N}g(i)\sum\limits_{d|{N\over i}}\mu(d) =iNg(i)diNμ(d)
不急,因为我们有性质一
i = N i=N i=N
g ( N ) ∗ 1 g(N)*1 g(N)1
i < N i<N i<N
∑ i ∣ N g ( i ) ∗ 0 \sum\limits_{i|N}g(i)*0 iNg(i)0
综上
g ( N ) = ∑ i ∣ N g ( i ) ∑ d ∣ N i μ ( d ) = g ( N ) g(N)=\sum\limits_{i|N}g(i)\sum\limits_{d|{N\over i}}\mu(d)=g(N) g(N)=iNg(i)diNμ(d)=g(N)得证!

##应用
然而莫比乌斯函数怎么求?
可以用线性筛法!

void getprime(int lim)
{
	int i,j,num=0;
	fo(i,2,lim) 
	{
		if (!bz[i]) 
		{
			prime[++num]=i;
			mu[i]=-1;//质数就是一个质因子
		} 
		for(j=1;i*prime[j]<=lim&&j<=num;j++)
		{
			bz[i*prime[j]]=1;
			if (prime[j]==i) break;
			if (!(i%prime[j])) 
			{
				mu[i*prime[j]]=0; //显然prime[j]在i*prime[j]中指数大于等于2
				break;
			} 
			mu[i*prime[j]]=-mu[i];//多加了一个质因子乘上-1
		} 
	}
}

事实上,莫比乌斯反演还有个变形

f ( k ) = ∑ i = 1 ⌊ n k ⌋ g ( i k ) \Large f(k)=\sum\limits_{i=1}^{\lfloor{n\over k}\rfloor} g(ik) f(k)=i=1kng(ik)

g ( k ) = ∑ i = 1 ⌊ n k ⌋ f ( i k ) μ ( i ) \Large g(k)=\sum\limits_{i=1}^{\lfloor{n\over k}\rfloor}f(ik)\mu(i) g(k)=i=1knf(ik)μ(i)

证明类似上面的证法,此处不再赘述。若有兴趣着可以参考度娘。

它可以非常好的应用在一些问题,比如说

f ( N ) f(N) f(N)不好求,但是 ∑ i ∣ N f ( i ) \sum\limits_{i|N} f(i) iNf(i)好求,可以设为 g ( N ) g(N) g(N)再用莫比乌斯反演解决。

##例题([HAOI2011][BZOJ2301]Problem b)

对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。

我们有这个
g ( k ) g(k) g(k)表示 1 ≤ x ≤ N , 1 ≤ y ≤ M , g c d ( x , y ) = k 1\leq x\leq N,1\leq y\leq M,gcd(x,y)=k 1xN,1yM,gcd(x,y)=k ( x , y ) (x,y) (x,y)对数

f ( k ) f(k) f(k)表示 1 ≤ x ≤ N , 1 ≤ y ≤ M , k ∣ g c d ( x , y ) 1\leq x\leq N,1\leq y\leq M,k|gcd(x,y) 1xN,1yM,kgcd(x,y) ( x , y ) (x,y) (x,y)对数

那么显然有 f ( k ) = ∑ i = 1 ⌊ n k ⌋ g ( i k ) \Large f(k)=\sum\limits_{i=1}^{\lfloor{n\over k}\rfloor} g(ik) f(k)=i=1kng(ik)(此处我们假设 N ≤ M N\leq M NM

f ( k ) f(k) f(k)非常好求,设 x = k x 1 , y = k y 1 x=kx_1,y=ky_1 x=kx1,y=ky1,那么只需要 1 ≤ x 1 ≤ ⌊ N k ⌋ , 1 ≤ y 1 ≤ ⌊ M k ⌋ \large 1\leq x1\leq {\lfloor{N\over k}\rfloor},1\leq y1\leq {\lfloor{M\over k}\rfloor} 1x1kN,1y1kM

f ( k ) = ⌊ N k ⌋ ⌊ M k ⌋ f(k)={\lfloor{N\over k}\rfloor}{\lfloor{M\over k}\rfloor} f(k)=kNkM 然后再使用莫比乌斯反演求解

这里可能会超时,所以对于 ⌊ N k ⌋ ⌊ M k ⌋ {\lfloor{N\over k}\rfloor}{\lfloor{M\over k}\rfloor} kNkM,可能有很多一部分是相等的,可以用分块解决,单次询问的复杂度就变成了 O ( N + M ) O(\sqrt N+\sqrt M) O(N +M )
附代码

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
long long mu[50005];
int a,b,c,d,k;
int prime[50005],n;
bool bz[50005];
void getprime(int lim)
{
	int i,j,num=0;
	fo(i,2,lim) 
	{
		if (!bz[i]) 
		{
			prime[++num]=i;
			mu[i]=-1;
		} 
		for(j=1;i*prime[j]<=lim&&j<=num;j++)
		{
			if (i*prime[j]>50000) break;
			bz[i*prime[j]]=1;
			if (prime[j]==i) break;
			if (!(i%prime[j])) 
			{
				mu[i*prime[j]]=0; 
				break;
			} 
			mu[i*prime[j]]=-mu[i];
		} 
	}
}
int find(int k,int mx,int my)
{
	 int i=1,j;
	 long long ans=0;
	 while(i<=trunc(min(mx,my)/k))
	 { 
	 	j=min(mx/(mx/i),my/(my/i)); 
	 	ans+=trunc(my/(i*k))*trunc(mx/(i*k))*(mu[j]-mu[i-1]);
	 	i=j+1;
	 }
	 return (int)ans;  
}
int main()
{
	freopen("inversion.in","r",stdin);
	getprime(50000);
	scanf("%d",&n);
	mu[1]=1;
	int i;
	fo(i,2,50000) mu[i]+=mu[i-1];
	while(n-->0) 
	{
		scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
		printf("%d\n",(int)(find(k,b,d)-find(k,a-1,d)-find(k,b,c-1)+find(k,a-1,c-1)));
	}
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值