莫比乌斯函数
莫比乌斯函数,定义如下:
-
若 d = 1 d=1 d=1则 μ ( d ) = 1 μ(d)=1 μ(d)=1
-
若 d = p 1 p 2 … p k d=p_1p_2\dots p_k d=p1p2…pk为互异素数,那么 μ ( d ) = ( − 1 ) k μ(d)=(-1)^k μ(d)=(−1)k
-
其它情况下 μ ( d ) = 0 μ(d)=0 μ(d)=0
莫比乌斯函数的性质
对于任意正整数 n n n有:
若 n = 1 , ∑ d ∣ n μ ( d ) = 1 n=1,\sum\limits_{d|n}μ(d)=1 n=1,d∣n∑μ(d)=1
若 n > 1 , ∑ d ∣ n μ ( d ) = 0 n>1,\sum\limits_{d|n}μ(d)=0 n>1,d∣n∑μ(d)=0
证明:
-
当 n = 1 n=1 n=1时显然
-
当 n > 1 n>1 n>1时,将分解可以得到 n = p 1 a 1 p 2 a 2 … p k a k n=p^{a_{1}}_{1}p^{a_{2}}_{2}\dots p^{a_{k}}_{k} n=p1a1p2a2…pkak
在 n n n的所有因子中, μ μ μ值不为零的只有所有质因子次数都为1的因子,其中质因数个数为 r r r个的因子有 C k r C^r_{k} Ckr个。
那么显然有:
∑ d ∣ n μ ( d ) = C k 0 − C k 1 + C k 2 − ⋯ + ( − 1 ) k C k k = ∑ i = 0 k ( − 1 ) i C k i \sum\limits_{d|n}μ(d)=C^0_{k}-C^1_{k}+C^2_{k}-\dots+(-1)^k C^k_{k}=\sum\limits^k_{i=0}(-1)^i C^i_{k} d∣n∑μ(d)=Ck0−Ck1+Ck2−⋯+(−1)kCkk=i=0∑k(−1)iCki
只需证明 ∑ i = 0 n ( − 1 ) i C n i = 0 ( n ∈ N + ) \sum\limits^n_{i=0}(-1)^i C^i_{n}=0(n\in N_{+}) i=0∑n(−1)iCni=0(n∈N+)即可。
二项式定理: ( x + y ) n = ∑ i = 0 n C n i x i y ( n − i ) (x+y)^n=\sum\limits^n_{i=0}C^i_{n}x^iy^{(n-i)} (x+y)n=i=0∑nCnixiy(n−i)
令 x = − 1 , y = 1 , x=-1,y=1, x=−1,y=1,代入即可得证 ∑ d ∣ n μ ( d ) = ∑ i = 0 k ( − 1 ) i C k i = ( 1 − 1 ) k = 0 \sum\limits_{d|n}μ(d)=\sum\limits^k_{i=0}(-1)^i C^i_{k}=(1-1)^k=0 d∣n∑μ(d)=i=0∑k(−1)iCki=(1−1)k=0
由于莫比乌斯函数是积性函数,因此我们可以通过欧拉筛来求出莫比乌斯函数的值。
code
void gtmu(){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!np[i]){
p[++p[0]]=i;
mu[i]=-1;
}
for(int j=1;j<=p[0]&&p[j]*i<=n;j++){
np[p[j]*i]=1;
if(i%p[j]==0){
mu[p[j]*i]=0;
break;
}
mu[p[j]*i]=-mu[i];
}
}
}
莫比乌斯反演
公式1
若 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum\limits_{d|n}f(d) F(n)=d∣n∑f(d),则有 f ( n ) = ∑ d ∣ n μ ( d ) F ( n d ) f(n)=\sum\limits_{d|n}μ(d)F(\frac{n}{d}) f(n)=d∣n∑μ(d)F(dn)
证明:
∑ d ∣ n μ ( d ) F ( n d ) = ∑ d ∣ n μ ( d ) ∑ k ∣ n d f ( k ) = ∑ k ∣ n f ( k ) ∑ d ∣ n k μ ( d ) = f ( n ) \sum\limits_{d|n}μ(d)F(\frac{n}{d})=\sum\limits_{d|n}μ(d)\sum\limits_{k|\frac{n}{d}}f(k)=\sum\limits_{k|n}f(k)\sum\limits_{d|\frac{n}{k}}μ(d)=f(n) d∣n∑μ(d)F(dn)=d∣n∑μ(d)k∣dn∑f(k)=k∣n∑f(k)d∣kn∑μ(d)=f(n)
公式2
若 F ( n ) = ∑ n ∣ d f ( d ) F(n)=\sum\limits_{n|d}f(d) F(n)=n∣d∑f(d),则有 f ( n ) = ∑ n ∣ d μ ( d n ) F ( d ) f(n)=\sum\limits_{n|d}μ(\frac{d}{n})F(d) f(n)=n∣d∑μ(nd)F(d)
证明:
∑ n ∣ d μ ( d n ) F ( d ) = ∑ n ∣ d μ ( d n ) ∑ d ∣ k f ( k ) = ∑ n ∣ k f ( k ) ∑ d ∣ k n μ ( d ) = f ( n ) \sum\limits_{n|d}μ(\frac{d}{n})F(d)=\sum\limits_{n|d}μ(\frac{d}{n})\sum\limits_{d|k}f(k)=\sum\limits_{n|k}f(k)\sum\limits_{d|\frac{k}{n}}μ(d)=f(n) n∣d∑μ(nd)F(d)=n∣d∑μ(nd)d∣k∑f(k)=n∣k∑f(k)d∣nk∑μ(d)=f(n)
以上两个公式的证明都用到了莫比乌斯函数的性质。
作用
对于一些函数 f ( n ) f(n) f(n),如果我们很难直接求出它的值,而容易求出倍数和或约数和 F ( n ) F(n) F(n),那么我们可以通过莫比乌斯反演求得 f ( n ) f(n) f(n)的值。
例: f ( n ) f(n) f(n)表示某一范围内 ( x , y ) = n (x,y)=n (x,y)=n的数对的数量, F ( n ) F(n) F(n)表示某一范围内 n ∣ ( x , y ) n|(x,y) n∣(x,y) 的数对的数量。那么直接求 f ( n ) f(n) f(n)并不是很好求,而 F ( n ) F(n) F(n)求起来相对简单一些,我们通过对 F ( n ) F(n) F(n)进行莫比乌斯反演来求得 f ( n ) f(n) f(n)。
例题
题目大意:求有多少数对 ( x , y ) (x,y) (x,y) ( 1 < = x < = n , 1 < = y < = m ) (1<=x<=n,1<=y<=m) (1<=x<=n,1<=y<=m)满足 g c d ( x , y ) gcd(x,y) gcd(x,y)为质数。
即求
∑ k = 1 n ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = k ] ( k ∈ p r i m e ) \sum\limits^n_{k=1}\sum\limits^n_{i=1}\sum\limits^m_{j=1}[gcd(i,j)==k]\qquad(k\in prime) k=1∑ni=1∑nj=1∑m[gcd(i,j)==k](k∈prime)
两边同时除以 k k k,将 [ g c d ( i , j ) = = k ] [gcd(i,j)==k] [gcd(i,j)==k]化成 [ g c d ( i , j ) = = 1 ] [gcd(i,j)==1] [gcd(i,j)==1]
∑ k = 1 n ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ [ g c d ( i , j ) = = 1 ] ( k ∈ p r i m e ) \sum\limits^n_{k=1}\sum\limits^{⌊\frac{n}{k}⌋}_{i=1}\sum\limits^{⌊\frac{m}{k}⌋}_{j=1}[gcd(i,j)==1]\qquad(k\in prime) k=1∑ni=1∑⌊kn⌋j=1∑⌊km⌋[gcd(i,j)==1](k∈prime)
我们知道莫比乌斯函数的性质
∑ d ∣ n μ ( d ) = [ n = = 1 ] \sum\limits_{d|n}μ(d)=[n==1] d∣n∑μ(d)=[n==1]
我们把 n n n换成 g c d ( i , j ) gcd(i,j) gcd(i,j),得 [ g c d ( i , j ) = = 1 ] = ∑ d ∣ g c d ( i , j ) μ ( d ) [gcd(i,j)==1]=\sum\limits_{d|gcd(i,j)}μ(d) [gcd(i,j)==1]=d∣gcd(i,j)∑μ(d)
原式变为
∑ k = 1 n ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ ∑ d ∣ g c d ( i , j ) μ ( d ) ( k ∈ p r i m e ) \sum\limits^n_{k=1}\sum\limits^{⌊\frac{n}{k}⌋}_{i=1}\sum\limits^{⌊\frac{m}{k}⌋}_{j=1}\sum\limits_{d|gcd(i,j)}μ(d)\qquad(k\in prime) k=1∑ni=1∑⌊kn⌋j=1∑⌊km⌋d∣gcd(i,j)∑μ(d)(k∈prime)
枚举 d d d
∑ k = 1 n ∑ d = 1 ⌊ n k ⌋ μ ( d ) ∗ ⌊ n k d ⌋ ∗ ⌊ m k d ⌋ ( k ∈ p r i m e ) \sum\limits^n_{k=1}\sum\limits^{⌊\frac{n}{k}⌋}_{d=1}μ(d)*⌊\frac{n}{kd}⌋*⌊\frac{m}{kd}⌋\qquad(k\in prime) k=1∑nd=1∑⌊kn⌋μ(d)∗⌊kdn⌋∗⌊kdm⌋(k∈prime)
令 T = k d T=kd T=kd,有
∑ k = 1 n ∑ d = 1 ⌊ n k ⌋ μ ( d ) ∗ ⌊ n T ⌋ ∗ ⌊ m T ⌋ ( k ∈ p r i m e ) \sum\limits^n_{k=1}\sum\limits^{⌊\frac{n}{k}⌋}_{d=1}μ(d)*⌊\frac{n}{T}⌋*⌊\frac{m}{T}⌋\qquad(k\in prime) k=1∑nd=1∑⌊kn⌋μ(d)∗⌊Tn⌋∗⌊Tm⌋(k∈prime)
枚举 T T T,提到前面
∑ T = 1 n ⌊ n T ⌋ ∗ ⌊ m T ⌋ ∑ k ∣ T , k ∈ p r i m e μ ( T k ) \sum\limits^n_{T=1}⌊\frac{n}{T}⌋*⌊\frac{m}{T}⌋\sum\limits_{k|T,k\in prime}μ(\frac{T}{k}) T=1∑n⌊Tn⌋∗⌊Tm⌋k∣T,k∈prime∑μ(kT)
用数论分块处理即可,时间复杂度为 O ( n ln n + T n ) O(n\ln n+T\sqrt n) O(nlnn+Tn)。
code
#include<bits/stdc++.h>
#define N 10000000
using namespace std;
int t,n,m,fl[N+5],p[N+5],mu[N+5],f[N+5];
long long ans,sum[N+5];
void dd(){
mu[1]=1;
for(int i=2;i<=N;i++){
if(!fl[i]){
p[++p[0]]=i;mu[i]=-1;
}
for(int j=1;j<=p[0]&&i*p[j]<=N;j++){
fl[i*p[j]]=1;
if(i%p[j]==0){
mu[i*p[j]]=0;
break;
}
mu[i*p[j]]=-mu[i];
}
}
for(int i=1;i<=p[0];i++){
for(int j=1;p[i]*j<=N;j++){
f[p[i]*j]+=mu[j];
}
}
for(int i=1;i<=N;i++){
sum[i]=sum[i-1]+f[i];
}
}
void ss(){
ans=0;
for(int l=1,r=0;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(sum[r]-sum[l-1])*(n/l)*(m/l);
}
}
int main()
{
dd();
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
ss();
printf("%lld\n",ans);
}
return 0;
}