##首先
…
\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)=i∣N∑g(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)=i∣N∑f(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 k≥2
所以我们就有 g ( N ) = ∑ i ∣ N f ( i ) μ ( N i ) \Large g(N)=\sum\limits_{i|N} f(i)\mu({N\over i}) g(N)=i∣N∑f(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)=i∣N∑f(iN)μ(i)
这个函数就是莫比乌斯函数
##证明?
首先,莫比乌斯函数有几个性质。
- 性质一
∑
d
∣
n
μ
(
d
)
=
0
∣
n
∈
N
∗
,
n
>
1
\sum\limits_{d|n}\mu(d)=0|n\in N^*,n>1
d∣n∑μ(d)=0∣n∈N∗,n>1
∑ d ∣ n μ ( d ) = 1 ∣ n = 1 \sum\limits_{d|n}\mu(d)=1|n=1 d∣n∑μ(d)=1∣n=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)=μ(p∗q)
先证性质一。
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=P1k1P2k2P3k3⋯Pmkm,
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}
d∣n∑μ(d)=r=0∑m(−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=0∑m(−1)rCmr=r=0∑mCmr(−1)r1m−r=(−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)=d∣N∑g(d)⇒g(N)=d∣N∑f(dn)μ(d)=d∣N∑μ(d)i∣dN∑g(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)
=i∣N∑g(i)d∣iN∑μ(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
i∣N∑g(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)=i∣N∑g(i)d∣iN∑μ(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=1∑⌊kn⌋g(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=1∑⌊kn⌋f(ik)μ(i)
证明类似上面的证法,此处不再赘述。若有兴趣着可以参考度娘。
它可以非常好的应用在一些问题,比如说
f ( N ) f(N) f(N)不好求,但是 ∑ i ∣ N f ( i ) \sum\limits_{i|N} f(i) i∣N∑f(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
1≤x≤N,1≤y≤M,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) 1≤x≤N,1≤y≤M,k∣gcd(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=1∑⌊kn⌋g(ik)(此处我们假设 N ≤ M N\leq M N≤M)
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} 1≤x1≤⌊kN⌋,1≤y1≤⌊kM⌋
故 f ( k ) = ⌊ N k ⌋ ⌊ M k ⌋ f(k)={\lfloor{N\over k}\rfloor}{\lfloor{M\over k}\rfloor} f(k)=⌊kN⌋⌊kM⌋ 然后再使用莫比乌斯反演求解
这里可能会超时,所以对于
⌊
N
k
⌋
⌊
M
k
⌋
{\lfloor{N\over k}\rfloor}{\lfloor{M\over k}\rfloor}
⌊kN⌋⌊kM⌋,可能有很多一部分是相等的,可以用分块解决,单次询问的复杂度就变成了
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)));
}
}