积性函数
积性函数 指对于所有互质的整数 a a a 和 b b b 有性质 f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f(ab)=f(a)f(b) 的数论函数。
特别地,若所有的整数
a
a
a 和
b
b
b 有性质
f
(
a
b
)
=
f
(
a
)
f
(
b
)
f(ab)=f(a)f(b)
f(ab)=f(a)f(b),则称这个函数
f
(
x
)
f(x)
f(x) 是 完全积性函数。
常见积性函数及其性质
-
Mobius 函数。 ∀ n ∈ N ∗ \forall n\in\N^* ∀n∈N∗ 有 μ ( n ) = { 1 , n = 1 ( − 1 ) k , n = ∏ i = 1 k p k , 0 , otherwise. \mu(n)=\begin{cases}1,n=1\\ (-1)^k,n=\prod_{i=1}^{k}{p_k},\\ 0,\text{otherwise.}\end{cases} μ(n)=⎩⎪⎨⎪⎧1,n=1(−1)k,n=∏i=1kpk,0,otherwise.
其中 p p p 是互不相同的素数; -
Euler 函数。 φ ( n ) \varphi(n) φ(n) 表示不大于 n n n 的、与 n n n 互素的数的个数;
-
约数个数函数。 d ( n ) d(n) d(n) 表示 n n n 的约数个数;
-
约数和函数。 σ ( n ) \sigma(n) σ(n) 表示 n n n 的约数之和。
完全积性函数
-
元函数。 ϵ ( x ) = [ x = 1 ] \epsilon(x)=[x=1] ϵ(x)=[x=1]。
-
恒等函数。 I ( x ) = 1 I(x)=1 I(x)=1。所谓恒等就是函数值恒等于 1 1 1。
-
单位函数。 i d ( n ) = n id(n)=n id(n)=n。
Dirichlet (狄利克雷)卷积
两个数论函数 f ( x ) , g ( x ) f(x),g(x) f(x),g(x) 的 Dirichlet 卷积 h ( x ) = ( f ∗ g ) ( x ) = ∑ d ∣ x f ( d ) g ( x d ) h(x)=(f*g)(x)=\sum_{d|x}f(d)g(\frac xd) h(x)=(f∗g)(x)=d∣x∑f(d)g(dx)
显然,Dirichlet 卷积满足交换律、结合律、分配律。而且有
f
∗
ϵ
=
f
f*\epsilon=f
f∗ϵ=f
Mobius 函数的性质
∀ n ∈ N ∗ \forall n\in\N^* ∀n∈N∗ 有 ∑ d ∣ n μ ( d ) = ϵ ( n ) \sum_{d|n}\mu(d)=\epsilon(n) d∣n∑μ(d)=ϵ(n)即 μ ∗ I = ϵ \mu*I=\epsilon μ∗I=ϵ
Euler 函数的性质
∀
n
∈
N
∗
\forall n\in\N^*
∀n∈N∗ 有
∑
d
∣
n
φ
(
d
)
=
n
\sum_{d|n}\varphi(d)=n
d∣n∑φ(d)=n即
φ
∗
I
=
i
d
\varphi*I=id
φ∗I=id
Mobius 反演
Mobius 反演(莫比乌斯反演) 是数论数学中很重要的内容,可以用于解决很多组合数学的问题。
结论 设
f
,
g
f,g
f,g 为数论函数,且
f
=
∑
d
∣
n
g
(
d
)
f=\sum_{d|n}g(d)
f=d∣n∑g(d)则
g
=
∑
d
∣
n
μ
(
d
)
f
(
n
d
)
g=\sum_{d|n}\mu(d)f(\frac nd)
g=d∣n∑μ(d)f(dn)
证明: 易知
f
=
g
∗
I
f=g*I
f=g∗I
左右两边同时卷上
μ
\mu
μ,得
f
∗
μ
=
g
∗
I
∗
μ
f*\mu=g*I*\mu
f∗μ=g∗I∗μ
因为
μ
∗
I
=
ϵ
\mu*I=\epsilon
μ∗I=ϵ,则有
f
∗
μ
=
g
f*\mu=g
f∗μ=g即
g
=
∑
d
∣
n
μ
(
d
)
f
(
n
d
)
g=\sum_{d|n}\mu(d)f(\frac nd)
g=d∣n∑μ(d)f(dn)原命题得证。
事实上,我们做题的时候主要用以下形式。
若
F
(
x
)
=
∑
x
∣
d
f
(
d
)
F(x)=\sum_{x|d}f(d)
F(x)=x∣d∑f(d)则有
f
(
x
)
=
∑
x
∣
d
μ
(
d
x
)
F
(
d
)
f(x)=\sum_{x|d}\mu(\frac dx)F(d)
f(x)=x∣d∑μ(xd)F(d)证明与上类似,此略。
杜教筛
杜教筛 是在低于线性的时间复杂度,求一个积性函数前缀和的算法。
(找不到定义,只好自己编一个)
和式的推导
今需计算积性函数
f
(
x
)
f(x)
f(x) 的前缀和
S
(
n
)
=
∑
i
=
1
n
f
(
i
)
S(n)=\sum_{i=1}^{n}{f(i)}
S(n)=i=1∑nf(i)
为了解决这个问题,构造积性函数
g
(
x
)
,
h
(
x
)
g(x),h(x)
g(x),h(x) 使
f
∗
g
=
h
f*g=h
f∗g=h
则
∑
i
=
1
n
h
(
x
)
=
∑
i
=
1
n
f
(
x
)
∗
g
(
x
)
=
∑
i
=
1
n
∑
d
∣
n
f
(
d
)
g
(
n
d
)
=
∑
d
=
1
n
g
(
d
)
⋅
∑
i
=
1
⌊
n
d
⌋
f
(
i
)
=
∑
d
=
1
n
g
(
d
)
⋅
S
(
⌊
n
d
⌋
)
=
g
(
1
)
⋅
S
(
n
)
+
∑
d
=
2
n
g
(
d
)
⋅
S
(
⌊
n
d
⌋
)
\begin{aligned}\sum_{i=1}^{n}h(x)&=\sum_{i=1}^{n}f(x)*g(x)\\ &=\sum_{i=1}^{n}\sum_{d|n}f(d)g(\frac nd)\\ &=\sum_{d=1}^{n}g(d)·\sum_{i=1}^{\lfloor\frac nd\rfloor}{f(i)}\\ &=\sum_{d=1}^n{g(d)}·S(\lfloor\frac nd\rfloor)\\ &=g(1)·S(n)+\sum_{d=2}^{n}g(d)·S(\lfloor\frac nd\rfloor)\end{aligned}
i=1∑nh(x)=i=1∑nf(x)∗g(x)=i=1∑nd∣n∑f(d)g(dn)=d=1∑ng(d)⋅i=1∑⌊dn⌋f(i)=d=1∑ng(d)⋅S(⌊dn⌋)=g(1)⋅S(n)+d=2∑ng(d)⋅S(⌊dn⌋)
所以
g
(
1
)
⋅
S
(
n
)
=
∑
i
=
1
n
h
(
i
)
−
∑
d
=
2
n
g
(
d
)
⋅
S
(
⌊
n
d
⌋
)
g(1)·S(n)=\sum_{i=1}^{n}{h(i)}-\sum_{d=2}^{n}{g(d)·S(\lfloor\frac nd\rfloor)}
g(1)⋅S(n)=i=1∑nh(i)−d=2∑ng(d)⋅S(⌊dn⌋)
那么问题来了, g , h g,h g,h 到底取什么呢?
例 1
求
S
(
n
)
=
∑
i
=
1
n
μ
(
i
)
S(n)=\sum_{i=1}^{n}{\mu(i)}
S(n)=i=1∑nμ(i)
由上面的套路,得
g
(
1
)
⋅
S
(
n
)
=
∑
i
=
1
n
h
(
x
)
−
∑
d
=
2
n
g
(
d
)
⋅
S
(
⌊
n
d
⌋
)
g(1)·S(n)=\sum_{i=1}^{n}{h(x)}-\sum_{d=2}^{n}{g(d)·S(\lfloor\frac nd\rfloor)}
g(1)⋅S(n)=i=1∑nh(x)−d=2∑ng(d)⋅S(⌊dn⌋)
因为
μ
∗
I
=
ϵ
\mu*I=\epsilon
μ∗I=ϵ,所以不妨令
g
=
I
,
h
=
ϵ
g=I,h=\epsilon
g=I,h=ϵ 得
I
(
1
)
⋅
S
(
n
)
=
∑
i
=
1
n
ϵ
(
x
)
−
∑
d
=
2
n
I
(
d
)
⋅
S
(
⌊
n
d
⌋
)
S
(
n
)
=
1
−
∑
d
=
2
n
S
(
⌊
n
d
⌋
)
\begin{aligned}I(1)·S(n)&=\sum_{i=1}^{n}{\epsilon(x)}-\sum_{d=2}^{n}{I(d)·S(\lfloor\frac nd\rfloor)}\\ S(n)&=1-\sum_{d=2}^{n}{S(\lfloor\frac nd\rfloor)}\end{aligned}
I(1)⋅S(n)S(n)=i=1∑nϵ(x)−d=2∑nI(d)⋅S(⌊dn⌋)=1−d=2∑nS(⌊dn⌋)
例 2
求
S
(
n
)
=
∑
i
=
1
n
φ
(
i
)
S(n)=\sum_{i=1}^{n}{\varphi(i)}
S(n)=i=1∑nφ(i)
容易想到
φ
∗
I
=
i
d
\varphi*I=id
φ∗I=id
由上面的套路得
S
(
n
)
=
∑
i
=
1
n
i
−
∑
d
=
2
n
S
(
⌊
n
d
⌋
)
S(n)=\sum_{i=1}^{n}{i}-\sum_{d=2}^{n}{S(\lfloor \frac nd\rfloor)}
S(n)=i=1∑ni−d=2∑nS(⌊dn⌋)
luogu 杜教筛模板
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define reg register
typedef long long ll;
const int MAXN=5000010;
const int MOD=15e5+7;
int T,n;
bool vis[MAXN];
int p[MAXN];
int phi[MAXN];
int mu[MAXN];
ll S_phi[MAXN];
int S_mu[MAXN];
int Hmu[MOD+10];
ll Hphi[MOD+10];
int len=0;
void init(){
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;phi[1]=mu[1]=1;
for(reg ll i=2;i<=MAXN;++i){
if(vis[i]){
p[++len]=i;
phi[i]=i-1;
mu[i]=-1;
}
for(reg int j=1;j<=len&&(i*p[j]<=MAXN);++j){
vis[i*p[j]]=0;
if(i%p[j]!=0){
phi[i*p[j]]=phi[i]*(p[j]-1);
mu[i*p[j]]=-mu[i];
}
else{
phi[i*p[j]]=phi[i]*p[j];
mu[i*p[j]]=0;
break;
}
}
}
S_phi[0]=S_mu[0]=0;
for(reg int i=1;i<=MAXN;++i){
S_phi[i]=S_phi[i-1]+phi[i];
S_mu[i]=S_mu[i-1]+mu[i];
}
}
ll Sphi(int x){
if(x<MAXN) return S_phi[x];
if(Hphi[x%MOD]) return Hphi[x%MOD];
ll sum=0;
for(int l=2,r;l<=x;l=r+1){
r=x/(x/l);
sum+=Sphi(x/l)*(r-l+1);
}
ll s=(1ll+x)*x/2;
return Hphi[x%MOD]=s-sum;
}
int Smu(int x){
if(x<MAXN) return S_mu[x];
if(Hmu[x%MOD]) return Hmu[x%MOD];
ll sum=0;
for(int l=2,r;l<=x;l=r+1){
r=x/(x/l);
sum+=Smu(x/l)*(r-l+1);
}
return Hmu[x%MOD]=1-sum;
}
int main(){
init();
scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf("%lld %d\n",Sphi(n),Smu(n));
}
}