背景:
之前不会用
M
a
r
k
d
o
w
n
Markdown
Markdown,所以坑没有补。
定义:
以下除法默认向下去整。
对于一个形如
F
n
=
∑
d
∣
n
f
d
F_n=\sum_{d|n}f_d
Fn=∑d∣nfd的式子,用莫比乌斯反演得到了一个结论:
f
n
=
∑
d
∣
n
μ
(
d
)
∗
F
n
/
d
f_n=\sum\limits_{d|n}μ(d)*F_{n/d}
fn=d∣n∑μ(d)∗Fn/d。
证明可以考虑狄利克雷卷积(稍后补上)。
那么
μ
μ
μ的定义是什么呢?
当
n
=
1
n=1
n=1时,
μ
(
n
)
=
1
μ(n)=1
μ(n)=1。
当
n
>
1
n>1
n>1时,若
n
n
n能分为
k
k
k个互不相等的质因数乘积,则
μ
(
n
)
=
(
−
1
)
k
μ(n)=(-1)^k
μ(n)=(−1)k;
否则,
μ
(
n
)
=
0
μ(n)=0
μ(n)=0。
同时
μ
μ
μ是积性函数,因此可以用欧拉筛预处理
μ
μ
μ。
用法:
可是怎么用呢。
我们发现
μ
μ
μ函数存在一个性质:
∑
d
∣
n
μ
(
d
)
=
[
n
=
1
]
\sum\limits_{d|n}μ(d)=[n=1]
d∣n∑μ(d)=[n=1]。
证明可以考虑狄利克雷卷积(稍后补上)。
好像还是没有什么用(大雾…)?
别着急。
例题:
求 ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = 1 ] \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[gcd(i,j)=1] i=1∑nj=1∑n[gcd(i,j)=1]。
对于这样的题怎么做呢?
显然暴力的时间复杂度是:
Θ
(
n
2
)
\Theta(n^2)
Θ(n2)的。
好像很难…
细心的同学可以发现该式中的
g
c
d
(
i
,
j
)
=
1
gcd(i,j)=1
gcd(i,j)=1与
μ
μ
μ性质
[
n
=
1
]
[n=1]
[n=1]有些类似,不妨将其套入,得:
∑
i
=
1
n
∑
j
=
1
n
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\sum\limits_{d|gcd(i,j)}μ(d)
i=1∑nj=1∑nd∣gcd(i,j)∑μ(d)
更换枚举项,得:
∑
i
=
1
n
∑
j
=
1
n
∑
d
=
1
n
μ
(
d
)
[
d
∣
g
c
d
(
i
,
j
)
]
\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\sum\limits_{d=1}^{n}μ(d)[d|gcd(i,j)]
i=1∑nj=1∑nd=1∑nμ(d)[d∣gcd(i,j)]
将
∑
d
=
1
n
μ
(
d
)
\sum\limits_{d=1}^{n}μ(d)
d=1∑nμ(d)前置,得:
∑
d
=
1
n
μ
(
d
)
∑
i
=
1
n
∑
j
=
1
n
[
d
∣
g
c
d
(
i
,
j
)
]
\sum\limits_{d=1}^{n}μ(d)\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[d|gcd(i,j)]
d=1∑nμ(d)i=1∑nj=1∑n[d∣gcd(i,j)]
更换枚举项,得:
∑
d
=
1
n
μ
(
d
)
∑
i
=
1
n
/
d
∑
j
=
1
n
/
d
[
d
∣
(
g
c
d
(
i
,
j
)
∗
d
)
]
\sum\limits_{d=1}^{n}μ(d)\sum\limits_{i=1}^{n/d}\sum\limits_{j=1}^{n/d}[d|(gcd(i,j)*d)]
d=1∑nμ(d)i=1∑n/dj=1∑n/d[d∣(gcd(i,j)∗d)]
化简,得:
∑
d
=
1
n
μ
(
d
)
∑
i
=
1
n
/
d
∑
j
=
1
n
/
d
1
\sum\limits_{d=1}^{n}μ(d)\sum\limits_{i=1}^{n/d}\sum\limits_{j=1}^{n/d}1
d=1∑nμ(d)i=1∑n/dj=1∑n/d1
最后,得:
∑
d
=
1
n
μ
(
d
)
∗
⌊
n
d
⌋
∗
⌊
n
d
⌋
\sum\limits_{d=1}^{n}μ(d)*\Big\lfloor\dfrac{n}{d}\Big\rfloor*\Big\lfloor\dfrac{n}{d}\Big\rfloor
d=1∑nμ(d)∗⌊dn⌋∗⌊dn⌋
可以考虑用整除分块来加速,时间复杂度:
Θ
(
n
)
\Theta(\sqrt{n})
Θ(n)。
代码:
以这道题 P 4450 P4450 P4450 双亲数 或P3455 [POI2007]ZAP-Queries的代码为例题目,但求的是 g c d ( i , j ) = k gcd(i,j)=k gcd(i,j)=k的方案,具体可以看下面题表第一题的证明。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
int prime[1000010],mu[1000010],sum_mu[1000010];
bool bz[1000010];
int n,m,k;
void init(int ma)
{
bz[0]=bz[1]=true;
mu[1]=1;
int t=0;
for(int i=2;i<=ma;i++)
{
if(!bz[i]) prime[++t]=i,mu[i]=-1;
for(int j=1;j<=t&&i*prime[j]<=ma;j++)
{
bz[i*prime[j]]=true;
if(!(i%prime[j]))
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
for(int i=1;i<=n;i++)
sum_mu[i]=sum_mu[i-1]+mu[i];
}
LL solve(int n,int m,int k)
{
LL sum=0;
n/=k,m/=k;
for(int l=1,r;l<=min(n,m);l=r+1)
{
r=min(n/(n/l),m/(m/l));
sum+=((LL)n/l)*((LL)m/l)*((LL)sum_mu[r]-sum_mu[l-1]);
}
return sum;
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
init(max(n,m));
printf("%lld",solve(n,m,k));
}
总结
重点来了。
我们在化简式子时多考虑
∑
,
∏
\sum,\prod
∑,∏的性质,尝试化简。如果化简出形似
g
c
d
(
i
,
j
)
=
1
gcd(i,j)=1
gcd(i,j)=1的式子,可以考虑带入
μ
μ
μ的性质,再化简即可。
一般都需要用整除分块的套路,同时,一些题目也需要预处理一些可以被证明的积性函数。