莫比乌斯反演的若干性质:
F(n)和f(n)是定义在非负整数集合上的两个函数
其一般描述为(约数和
F(n)=∑d|nf(d)
F
(
n
)
=
∑
d
|
n
f
(
d
)
=>
f(n)=∑d|nμ(d)F(nd)
f
(
n
)
=
∑
d
|
n
μ
(
d
)
F
(
n
d
)
另一种描述为(倍数和
F(n)=∑n|df(d)
F
(
n
)
=
∑
n
|
d
f
(
d
)
=>
f(n)=∑n|dμ(dn)F(d)
f
(
n
)
=
∑
n
|
d
μ
(
d
n
)
F
(
d
)
mu(x),当x由y个互质的数相乘得到时,当y为奇数,mu(x)=-1,y为偶数,mu(x)=1;否则mu(x)=0;
莫比乌斯反演的一些技巧:
关于gcd求和(求gcd的值)
https://www.zybuluo.com/ruanxingzhi/note/753117
(orz
关于F与f
如果f中存在[xxx=d]的话,那么F中应当有一个[d|xxx]的状况,然后就能倍数和乱搞。
有关 μ(x) μ ( x ) 的用法
对于任意正整数n
所以对于任意gcd(i,j)==k的时候,都可以把这个k取出来,然后化成这个形式,然后对于每个d,d|gcd(i,j)时都提供mu(d)的贡献。然后分段求和,往往能够得到一个式子,有着较为优秀的复杂度。
(注意显然这个式子只能求gcd(i,j)=k的个数,无法求gcd(i,j)的值
因为mu是积性函数,所以可以线性筛得到mu的值
模板为
mu[1]=1;
for(int i=2;i<=n;++i)
{
if(!is[i]) prime[++prime[0]]=i,mu[i]=-1;
for(int j=1;j<=prime[0]&&i*prime[j]<=n;++j)
{
is[i*prime[j]]=1;
if(!(i%prime[j]))
{
mu[i*prime[j]]=0;;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
phi的一些用法
ϕ ϕ
意义是[1,n-1]中和n互质的数的个数。
有一些数不是质数所以求x在modp下的逆元可以用x^(phi(p)-1)来求。
x=∑d|xϕ(d)
x
=
∑
d
|
x
ϕ
(
d
)
所以面对gcd(i,j)求值问题时,可以把gcd(i,j)转化为以上问题,用phi来做。
又有
phi[i]=
∑d|kd∗μ(kd)
∑
d
|
k
d
∗
μ
(
k
d
)
,这个问题的转化我不会用。
求phi的板子
inline void get_phi(){
phi[1]=1;
for (int i=2;i<=n;++i){
if (!p[i]){
prime[++prime[0]]=i;
phi[i]=i-1;
}
for (int j=1;j<=prime[0]&&i*prime[j]<=n;++j){
p[i*prime[j]]=1;
if (i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
phi[i]+=phi[i-1];
}
}