一.数论函数的定义与一些基本的数论函数.
数论函数:数论函数定义为定义域为正整数且陪域为复数的函数.
积性函数:若有数论函数 f f f满足 gcd ( n , m ) = 1 \gcd(n,m)=1 gcd(n,m)=1时 f ( n m ) = f ( n ) f ( m ) f(nm)=f(n)f(m) f(nm)=f(n)f(m),则函数 f f f被称为积性函数.
完全积性函数:若有数论函数 f f f满足任何时候 f ( n m ) = f ( n ) f ( m ) f(nm)=f(n)f(m) f(nm)=f(n)f(m),则函数 f f f被称为完全积性函数.
接下来我们定义几个基本的数论函数.
元函数: e ( n ) = [ n = 1 ] e(n)=[n=1] e(n)=[n=1].
恒等函数: I ( n ) = 1 I(n)=1 I(n)=1.
单位函数: ε ( n ) = n \varepsilon(n)=n ε(n)=n.
约数个数函数: τ ( n ) = ∑ d ∣ n 1 \tau(n)=\sum_{d|n}1 τ(n)=∑d∣n1.
约数和函数: σ ( n ) = ∑ d ∣ n d \sigma(n)=\sum_{d|n}d σ(n)=∑d∣nd.
约数函数性质参见整除理论与线性丢番图方程相关.
欧拉函数: ϕ ( n ) = ∑ i = 1 n [ gcd ( i , n ) = 1 ] \phi(n)=\sum_{i=1}^{n}[\gcd(i,n)=1] ϕ(n)=∑i=1n[gcd(i,n)=1].
欧拉函数性质参见欧拉函数相关.
二.Dirichlet卷积及其计算.
Dirichlet卷积:定义两个数论函数
f
,
g
f,g
f,g的Dirichlet卷积
f
×
g
f\times g
f×g为:
(
f
×
g
)
(
n
)
=
∑
d
∣
n
f
(
d
)
g
(
n
d
)
(f\times g)(n)=\sum_{d|n}f(d)g\left(\frac{n}{d}\right)
(f×g)(n)=d∣n∑f(d)g(dn)
考虑如何计算两个数论函数的Dirichlet卷积,可以按照定义算,那样是 O ( n n ) O(n\sqrt{n}) O(nn)的.
还有一种 O ( n log n ) O(n\log n) O(nlogn)的计算方法是,将枚举因数改为枚举倍数,计算总贡献.
代码如下:
void Dir_mul(int *a,int *b,int n){
for (int i=n;i>=1;--i){
for (int j=2;i*j<=n;++j) a[i*j]+=a[i]*b[j];
a[i]*=b[1];
}
}
三.Dirichlet卷积的相关性质.
Dirichlet卷积的性质1:所有数论函数的Dirichlet卷积满足交换律,即:
f
×
g
=
g
×
f
f\times g=g\times f
f×g=g×f
证明:
(
f
×
g
)
(
n
)
=
∑
d
∣
n
f
(
d
)
g
(
n
d
)
=
(
g
×
f
)
(
n
)
(f\times g)(n)=\sum_{d|n}f(d)g\left(\frac{n}{d}\right)=(g\times f)(n)
(f×g)(n)=d∣n∑f(d)g(dn)=(g×f)(n)
证毕.
Dirichlet卷积的性质2:所有数论函数的Dirichlet卷积满足结合律,即:
f
×
g
×
h
=
f
×
(
g
×
h
)
f\times g\times h=f\times (g\times h)
f×g×h=f×(g×h)
证明:
(
f
×
g
×
h
)
(
n
)
=
∑
t
d
3
=
n
(
∑
d
1
d
2
=
t
f
(
d
1
)
g
(
d
2
)
)
h
(
d
3
)
=
∑
d
1
d
2
d
3
=
n
f
(
d
1
)
g
(
d
2
)
h
(
d
3
)
=
∑
d
1
t
=
n
f
(
d
1
)
∑
d
2
d
3
=
t
g
(
d
2
)
h
(
d
3
)
=
(
f
×
(
g
×
h
)
)
(
n
)
(f\times g\times h)(n)\\ =\sum_{td_3=n}\left(\sum_{d_1d_2=t}f(d_1)g(d_2)\right)h(d_3)\\ =\sum_{d_1d_2d_3=n}f(d_1)g(d_2)h(d_3)\\ =\sum_{d_1t=n}f(d_1)\sum_{d_2d_3=t}g(d_2)h(d_3)\\ =(f\times (g\times h))(n)
(f×g×h)(n)=td3=n∑(d1d2=t∑f(d1)g(d2))h(d3)=d1d2d3=n∑f(d1)g(d2)h(d3)=d1t=n∑f(d1)d2d3=t∑g(d2)h(d3)=(f×(g×h))(n)
证毕.
Dirichlet卷积的性质3:所有数论函数的Dirichlet卷积关于加法满足分配律,即:
(
f
+
g
)
×
h
=
f
×
h
+
g
×
h
(f+g)\times h=f\times h+g\times h
(f+g)×h=f×h+g×h
证明:
(
(
f
+
g
)
×
h
)
(
n
)
=
∑
d
∣
n
(
f
(
d
)
+
g
(
d
)
)
h
(
n
d
)
=
∑
d
∣
n
f
(
d
)
h
(
n
d
)
+
∑
d
∣
n
g
(
d
)
h
(
n
d
)
=
(
f
×
h
)
(
n
)
+
(
g
×
h
)
(
n
)
((f+g)\times h)(n)\\ =\sum_{d|n}(f(d)+g(d))h\left(\frac{n}{d}\right)\\ =\sum_{d|n}f(d)h\left(\frac{n}{d}\right)+\sum_{d|n}g(d)h\left(\frac{n}{d}\right)\\ =(f\times h)(n)+(g\times h)(n)
((f+g)×h)(n)=d∣n∑(f(d)+g(d))h(dn)=d∣n∑f(d)h(dn)+d∣n∑g(d)h(dn)=(f×h)(n)+(g×h)(n)
证毕.
Dirichlet卷积的性质4:两个积性函数的Dirichlet卷积仍然是积性函数.
证明:
若在
gcd
(
n
,
m
)
=
1
\gcd(n,m)=1
gcd(n,m)=1时,有
f
(
n
m
)
=
f
(
n
)
f
(
m
)
,
g
(
n
m
)
=
g
(
n
)
g
(
m
)
f(nm)=f(n)f(m),g(nm)=g(n)g(m)
f(nm)=f(n)f(m),g(nm)=g(n)g(m),则:
(
f
×
g
)
(
n
)
(
f
×
g
)
(
m
)
=
(
∑
d
∣
n
f
(
d
)
g
(
n
d
)
)
(
∑
d
∣
m
f
(
d
)
g
(
m
d
)
)
=
∑
d
1
∣
n
∑
d
2
∣
m
f
(
d
1
)
g
(
n
d
1
)
f
(
d
2
)
g
(
m
d
2
)
=
∑
d
1
∣
n
∑
d
2
∣
m
f
(
d
1
d
2
)
g
(
n
m
d
1
d
2
)
=
∑
d
∣
n
m
f
(
d
)
g
(
n
m
d
)
=
(
f
×
g
)
(
n
m
)
(f\times g)(n)(f\times g)(m)\\ =\left(\sum_{d|n}f(d)g\left(\frac{n}{d}\right)\right)\left(\sum_{d|m}f(d)g\left(\frac{m}{d}\right)\right)\\ =\sum_{d_1|n}\sum_{d_2|m}f(d_1)g\left(\frac{n}{d_1}\right)f(d_2)g\left(\frac{m}{d_2}\right)\\ =\sum_{d_1|n}\sum_{d_2|m}f(d_1d_2)g\left(\frac{nm}{d_1d_2}\right)\\ =\sum_{d|nm}f(d)g\left(\frac{nm}{d}\right)\\ =(f\times g)(nm)
(f×g)(n)(f×g)(m)=⎝⎛d∣n∑f(d)g(dn)⎠⎞⎝⎛d∣m∑f(d)g(dm)⎠⎞=d1∣n∑d2∣m∑f(d1)g(d1n)f(d2)g(d2m)=d1∣n∑d2∣m∑f(d1d2)g(d1d2nm)=d∣nm∑f(d)g(dnm)=(f×g)(nm)
证毕.
三.Dirichlet卷积逆.
如何求一个数论函数的在Dirichlet卷积意义下的逆呢?
首先我们需要知道,Dirichlet卷积的单位元为元函数 e e e.
首先对于一个已知的数论函数
f
f
f,它的Dirichlet卷积逆
f
−
1
f^{-1}
f−1必然得满足:
f
(
1
)
f
−
1
(
1
)
=
1
⇒
f
−
1
(
1
)
=
1
f
(
1
)
f(1)f^{-1}(1)=1\Rightarrow f^{-1}(1)=\frac{1}{f(1)}
f(1)f−1(1)=1⇒f−1(1)=f(1)1
然后,我们考虑
n
>
1
n>1
n>1时构造
f
−
1
(
n
)
f^{-1}(n)
f−1(n):
∑
d
∣
n
f
−
1
(
d
)
f
(
n
d
)
=
0
f
−
1
(
n
)
f
(
1
)
+
∑
d
∣
n
∧
d
<
n
f
−
1
(
d
)
f
(
n
d
)
=
0
f
−
1
(
n
)
=
−
1
f
(
1
)
∑
d
∣
n
∧
d
<
n
f
−
1
(
d
)
f
(
n
d
)
\sum_{d|n}f^{-1}(d)f\left(\frac{n}{d}\right)=0\\ f^{-1}(n)f(1)+\sum_{d|n\wedge d<n}f^{-1}(d)f\left(\frac{n}{d}\right)=0\\ f^{-1}(n)=-\frac{1}{f(1)}\sum_{d|n\wedge d<n}f^{-1}(d)f\left(\frac{n}{d}\right)
d∣n∑f−1(d)f(dn)=0f−1(n)f(1)+d∣n∧d<n∑f−1(d)f(dn)=0f−1(n)=−f(1)1d∣n∧d<n∑f−1(d)f(dn)
所以我们有:
f
−
1
(
n
)
=
{
1
f
(
1
)
n
=
1
−
1
f
(
1
)
∑
d
∣
n
∧
d
<
n
f
−
1
(
d
)
f
(
n
d
)
n
>
1
f^{-1}(n)= \left\{\begin{matrix} \frac{1}{f(1)}&n=1\\ -\frac{1}{f(1)}\sum_{d|n\wedge d<n}f^{-1}(d)f\left(\frac{n}{d}\right)&n>1 \end{matrix}\right.
f−1(n)={f(1)1−f(1)1∑d∣n∧d<nf−1(d)f(dn)n=1n>1
同时我们知道了,一个数论函数
f
f
f存在Dirichlet卷积逆当且仅当
f
(
1
)
≠
0
f(1)\neq 0
f(1)=0.
四.Mobius函数.
Mobius函数:我们把恒等函数 I I I的Dirichlet卷积逆称为Mobius函数,记为 μ \mu μ.
现在我们来求一下 μ ( n ) \mu(n) μ(n)的具体数值.
首先,根据上面得出的结论,我们可以构造
μ
\mu
μ函数为:
μ
(
n
)
=
{
1
n
=
1
−
∑
d
∣
n
∧
d
<
n
μ
(
d
)
n
>
1
\mu(n)= \left\{\begin{matrix} 1&n=1\\ -\sum_{d|n\wedge d<n}\mu(d)&n>1 \end{matrix}\right.
μ(n)={1−∑d∣n∧d<nμ(d)n=1n>1
尝试打出一个表:
1
2
3
4
5
6
7
8
9
⋯
1
−
1
−
1
0
−
1
1
−
1
0
0
⋯
\begin{matrix} 1&2&3&4&5&6&7&8&9&\cdots\\ 1&-1&-1&0&-1&1&-1&0&0&\cdots \end{matrix}
112−13−1405−1617−18090⋯⋯
设唯一分解
n
=
∏
i
=
1
k
p
i
c
i
n=\prod_{i=1}^{k}p_i^{c_i}
n=∏i=1kpici,我们发现
μ
\mu
μ函数可能满足这么一个表达式:
μ
(
n
)
=
{
(
−
1
)
k
∀
i
,
c
i
=
1
0
∃
i
,
c
i
>
1
\mu(n)= \left\{\begin{matrix} (-1)^{k}&\forall i,c_i=1\\ 0&\exists i,c_i>1 \end{matrix}\right.
μ(n)={(−1)k0∀i,ci=1∃i,ci>1
证明:
首先当
n
=
1
n=1
n=1时,显然有
μ
(
1
)
I
(
1
)
=
e
(
1
)
\mu(1)I(1)=e(1)
μ(1)I(1)=e(1).
若
n
>
1
n>1
n>1,设唯一分解
n
=
∏
i
=
1
k
p
i
c
i
n=\prod_{i=1}^{k}p_i^{c_i}
n=∏i=1kpici,令
m
=
∏
i
=
1
k
p
i
m=\prod_{i=1}^{k}p_i
m=∏i=1kpi,则有:
∑
d
∣
n
μ
(
d
)
=
∑
d
∣
m
μ
(
d
)
\sum_{d|n}\mu(d)=\sum_{d|m}\mu(d)
d∣n∑μ(d)=d∣m∑μ(d)
此时仍然有
m
>
1
m>1
m>1,设
t
=
∏
i
=
1
k
−
1
p
i
c
i
t=\prod_{i=1}^{k-1}p_i^{c_i}
t=∏i=1k−1pici,则有:
∑
d
∣
m
μ
(
d
)
=
∑
d
∣
t
(
μ
(
d
)
+
μ
(
d
p
k
)
)
\sum_{d|m}\mu(d)=\sum_{d|t}(\mu(d)+\mu(dp_{k}))
d∣m∑μ(d)=d∣t∑(μ(d)+μ(dpk))
由于
μ
(
d
)
\mu(d)
μ(d)与
μ
(
d
p
k
)
\mu(dp_{k})
μ(dpk)必定为相反数,所以
μ
(
d
)
+
μ
(
d
p
k
)
=
0
\mu(d)+\mu(dp_{k})=0
μ(d)+μ(dpk)=0,即:
∑
d
∣
n
μ
(
d
)
=
∑
d
∣
t
0
=
0
\sum_{d|n}\mu(d)=\sum_{d|t}0=0
d∣n∑μ(d)=d∣t∑0=0
证毕.
现在我们得到了
μ
\mu
μ函数的一个通项公式.
五.Mobius函数的求解.
求解单个Mobius函数的方法非常简单,可以通过直接分解质因数做到 O ( n ) O(\sqrt{n}) O(n)求解.
代码入下:
int Get_mu(int n){
int res=1,now=n;
for (int i=2;i*i<=n;++i)
if (now%i==0){
if ((now/=i)%i==0) return 0;
res=-res;
}
return now>1?-res:res;
}
而显然,Mobius函数也非常容易用线性筛筛出.
时间复杂度 O ( n ) O(n) O(n).
代码如下:
int b[N+9],pr[N+9],cp;
int mu[N+9];
void Sieve(){
mu[1]=1;
for (int i=2;i<=n;++i){
if (!b[i]) pr[++cp]=i,mu[i]=-1;
for (int j=1;j<=cp&&i*pr[j]<=n;++j){
b[i*pr[j]]=1;
if (i%pr[j]==0) {mu[i*pr[j]]=0;break;}
mu[i*pr[j]]=-mu[i];
}
}
}
六.Mobius反演及其应用.
根据
I
×
μ
=
e
I\times \mu=e
I×μ=e,我们还可以推出一个反演:
f
=
I
×
g
⇔
g
=
μ
×
f
f=I\times g\Leftrightarrow g=\mu\times f
f=I×g⇔g=μ×f
将上述反演形式写成和式,我们就可以得到Mobius反演:
f
(
n
)
=
∑
d
∣
n
g
(
d
)
⇔
g
(
n
)
=
∑
d
∣
n
f
(
d
)
μ
(
n
d
)
f(n)=\sum_{d|n}g(d)\Leftrightarrow g(n)=\sum_{d|n}f(d)\mu\left(\frac{n}{d}\right)
f(n)=d∣n∑g(d)⇔g(n)=d∣n∑f(d)μ(dn)
Mobius反演的一个经典作用是和式变换,例如:
∑
i
=
1
n
∑
j
=
1
m
[
gcd
(
i
,
j
)
=
1
]
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
gcd
(
i
,
j
)
μ
(
d
)
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
i
∧
d
∣
j
μ
(
d
)
=
∑
d
=
1
min
(
n
,
m
)
μ
(
d
)
∑
i
=
1
⌊
n
d
⌋
∑
i
=
1
⌊
m
d
⌋
1
=
∑
d
=
1
min
(
n
,
m
)
μ
(
d
)
⌊
n
d
⌋
⌊
m
d
⌋
\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=1]\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|\gcd(i,j)}\mu(d)\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|i\wedge d|j}\mu(d)\\ =\sum_{d=1}^{\min(n,m)}\mu(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{i=1}^{\left\lfloor\frac{m}{d}\right\rfloor}1\\ =\sum_{d=1}^{\min(n,m)}\mu(d)\left\lfloor\frac{n}{d}\right\rfloor \left\lfloor\frac{m}{d}\right\rfloor
i=1∑nj=1∑m[gcd(i,j)=1]=i=1∑nj=1∑md∣gcd(i,j)∑μ(d)=i=1∑nj=1∑md∣i∧d∣j∑μ(d)=d=1∑min(n,m)μ(d)i=1∑⌊dn⌋i=1∑⌊dm⌋1=d=1∑min(n,m)μ(d)⌊dn⌋⌊dm⌋
然后通过经典的除法分块,我们可以做到
O
(
n
+
m
)
O(\sqrt{n}+\sqrt{m})
O(n+m)求解这个式子.
七.一些特殊的Dirichlet卷积.
卷积1: f × e = f f\times e=f f×e=f.
这就是元函数的作用…
卷积2: e = μ × I e=\mu\times I e=μ×I.
卷积3: ε = ϕ × I \varepsilon=\phi\times I ε=ϕ×I.
证明:
首先我们构造函数
f
=
ϕ
×
I
f=\phi\times I
f=ϕ×I,由于
ϕ
\phi
ϕ和
I
I
I都是积性函数,所以
f
f
f也是积性函数.
此时我们可以把
n
n
n写成唯一分解形式
n
=
∏
i
=
1
k
p
i
c
i
n=\prod_{i=1}^{k}p_i^{c_i}
n=∏i=1kpici,容易发现现在只需要证明:
∑
d
∣
p
i
c
i
ϕ
(
d
)
=
p
i
c
i
\sum_{d|p_i^{c_i}}\phi(d)=p_i^{c_i}
d∣pici∑ϕ(d)=pici
于是有:
∑
d
∣
p
i
c
i
ϕ
(
d
)
=
∑
j
=
0
c
i
ϕ
(
p
i
j
)
=
1
+
∑
j
=
0
c
i
−
1
(
p
i
−
1
)
p
i
j
=
1
+
(
p
i
−
1
)
1
−
p
i
c
i
1
−
p
i
=
1
+
p
i
c
i
−
1
=
p
i
c
i
\sum_{d|p_i^{c_i}}\phi(d)=\sum_{j=0}^{c_i}\phi(p_i^{j})\\ =1+\sum_{j=0}^{c_i-1}(p_i-1)p_i^{j}\\ =1+(p_i-1)\frac{1-p_i^{c_i}}{1-p_i}\\ =1+p_i^{c_i}-1\\ =p_i^{c_i}
d∣pici∑ϕ(d)=j=0∑ciϕ(pij)=1+j=0∑ci−1(pi−1)pij=1+(pi−1)1−pi1−pici=1+pici−1=pici
证毕.
卷积4: ϕ = μ × ε \phi=\mu\times \varepsilon ϕ=μ×ε.
证明:
考虑用容斥计算欧拉函数,设唯一分解
n
=
∏
i
=
1
k
p
i
c
i
n=\prod_{i=1}^{k}p_i^{c_i}
n=∏i=1kpici,我们可以得到:
ϕ
(
n
)
=
∑
T
⊆
[
k
]
(
−
1
)
∣
T
∣
n
∏
i
∈
T
p
i
\phi(n)=\sum_{T\subseteq [k]}(-1)^{|T|}\frac{n}{\prod_{i\in T}p_i}\\
ϕ(n)=T⊆[k]∑(−1)∣T∣∏i∈Tpin
令
m
=
∏
i
=
1
k
p
i
m=\prod_{i=1}^{k}p_i
m=∏i=1kpi,有:
ϕ
(
n
)
=
∑
d
∣
m
μ
(
d
)
n
d
\phi(n)=\sum_{d|m}\mu(d)\frac{n}{d}\\
ϕ(n)=d∣m∑μ(d)dn
对于满足
d
∣
n
d|n
d∣n却不满足
d
∣
m
d|m
d∣m的
d
d
d必然有
μ
(
d
)
=
0
\mu(d)=0
μ(d)=0,所以:
ϕ
(
n
)
=
∑
d
∣
n
μ
(
d
)
n
d
\phi(n)=\sum_{d|n}\mu(d)\frac{n}{d}
ϕ(n)=d∣n∑μ(d)dn
证毕.
八.杜教筛.
假设有一个数论函数
f
(
n
)
f(n)
f(n),考虑计算下式:
∑
i
=
1
n
f
(
n
)
\sum_{i=1}^{n}f(n)
i=1∑nf(n)
看起来除了一些非常简单的数论函数(例如 e , I , ε e,I,\varepsilon e,I,ε),怎么着我们也得用 O ( n ) O(n) O(n)的是时间复杂度来求出(例如 μ , ϕ \mu,\phi μ,ϕ).
但如果 f ( n ) f(n) f(n)有一些特殊的性质的话,我们也可以用低于 O ( n ) O(n) O(n)的时间复杂度求出!这也是接下来研究的重点.
我们先构造出两个数论函数 h , g h,g h,g满足 h = g × f h=g\times f h=g×f,且 h , g h,g h,g都非常好算.
那么我们有:
∑
i
=
1
n
h
(
i
)
=
∑
i
=
1
n
∑
d
∣
i
g
(
d
)
f
(
i
d
)
=
∑
d
=
1
n
g
(
d
)
∑
i
=
1
⌊
n
d
⌋
f
(
i
)
\sum_{i=1}^{n}h(i)=\sum_{i=1}^{n}\sum_{d|i}g(d)f\left(\frac{i}{d}\right)\\ =\sum_{d=1}^{n}g(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}f(i)
i=1∑nh(i)=i=1∑nd∣i∑g(d)f(di)=d=1∑ng(d)i=1∑⌊dn⌋f(i)
设:
S
(
i
)
=
∑
j
=
1
i
f
(
j
)
S(i)=\sum_{j=1}^{i}f(j)
S(i)=j=1∑if(j)
那么有:
∑
i
=
1
n
h
(
i
)
=
∑
d
=
1
n
g
(
d
)
S
(
⌊
n
d
⌋
)
∑
i
=
1
n
h
(
i
)
=
g
(
1
)
S
(
n
)
+
∑
d
=
2
n
g
(
d
)
S
(
⌊
n
d
⌋
)
g
(
1
)
S
(
n
)
=
∑
i
=
1
n
h
(
i
)
−
∑
d
=
2
n
g
(
d
)
S
(
⌊
n
d
⌋
)
S
(
n
)
=
1
g
(
1
)
(
∑
i
=
1
n
h
(
i
)
−
∑
d
=
2
n
g
(
d
)
S
(
⌊
n
d
⌋
)
)
\sum_{i=1}^{n}h(i)=\sum_{d=1}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\\ \sum_{i=1}^{n}h(i)=g(1)S(n)+\sum_{d=2}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\\ g(1)S(n)=\sum_{i=1}^{n}h(i)-\sum_{d=2}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\\ S(n)=\frac{1}{g(1)}\left(\sum_{i=1}^{n}h(i)-\sum_{d=2}^{n}g(d)S\left(\left\lfloor\frac{n}{d}\right\rfloor\right)\right)\\
i=1∑nh(i)=d=1∑ng(d)S(⌊dn⌋)i=1∑nh(i)=g(1)S(n)+d=2∑ng(d)S(⌊dn⌋)g(1)S(n)=i=1∑nh(i)−d=2∑ng(d)S(⌊dn⌋)S(n)=g(1)1(i=1∑nh(i)−d=2∑ng(d)S(⌊dn⌋))
递归计算就好了,而且根据取整函数的性质,需要算的前缀和只有 O ( n ) O(\sqrt{n}) O(n)个数 S ( ⌊ n i ⌋ ) S\left(\left\lfloor\frac{n}{i}\right\rfloor\right) S(⌊in⌋).
那么时间复杂度即为:
O
(
∑
i
=
1
⌊
n
⌋
(
i
+
n
i
)
)
=
O
(
n
1
2
∫
1
n
(
i
1
2
+
i
−
1
2
)
d
i
)
=
O
(
n
3
4
)
O\left(\sum_{i=1}^{\left\lfloor\sqrt{n}\right\rfloor}\left(\sqrt{i}+\sqrt{\frac{n}{i}}\right)\right)=O\left(n^{\frac{1}{2}}\int_{1}^{\sqrt{n}}\left(i^{\frac{1}{2}}+i^{-\frac{1}{2}}\right)\mathrm{d}i\right)=O(n^{\frac{3}{4}})
O⎝⎜⎛i=1∑⌊n⌋(i+in)⎠⎟⎞=O(n21∫1n(i21+i−21)di)=O(n43)
考虑线性筛预处理前
m
m
m个数的前缀和,那么时间复杂度变为:
O
(
∑
i
=
1
⌊
n
m
⌋
n
i
)
=
O
(
n
1
2
∫
1
n
m
i
−
1
2
d
i
)
=
O
(
n
m
+
m
)
O\left(\sum_{i=1}^{\left\lfloor\frac{n}{m}\right\rfloor}\sqrt{\frac{n}{i}}\right)=O\left(n^{\frac{1}{2}}\int_{1}^{\frac{n}{m}}i^{-\frac{1}{2}}\mathrm{d}i\right)=O\left(\frac{n}{\sqrt{m}}+m\right)
O⎝⎜⎛i=1∑⌊mn⌋in⎠⎟⎞=O(n21∫1mni−21di)=O(mn+m)
取 m = n 2 3 m=n^{\frac{2}{3}} m=n32最优,时间复杂度为 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32).
根据上面的卷积2和卷积3,不难写出杜教筛筛 μ \mu μ和 ϕ \phi ϕ的前缀和代码.
记忆化使用map实现应该是没有太大问题的,因为需要用map存的值只有 O ( n ) O(\sqrt{n}) O(n)级别个.
luogu4213代码如下(被卡常了两个点,手写hash即可过):
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100000,M=5000000;
int b[M+9],pr[M+9],cp;
LL mu[M+9],phi[M+9];
void Sieve(){
mu[1]=1;phi[1]=1;
for (int i=2;i<=M;++i){
if (!b[i]) pr[++cp]=i,mu[i]=-1,phi[i]=i-1;
for (int j=1;j<=cp&&i*pr[j]<=M;++j){
int t=i*pr[j];
b[t]=1;
if (i%pr[j]==0) {mu[t]=0;phi[t]=phi[i]*pr[j];break;}
mu[t]=-mu[i];phi[t]=phi[i]*(pr[j]-1);
}
}
for (int i=1;i<=M;++i) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
void start(){
Sieve();
}
LL n;
void into(){
scanf("%lld",&n);
}
map<LL,LL>sphi,smu;
LL ans0,ans1;
LL Get_sumphi(LL n){
if (n<=M) return phi[n];
if (sphi.find(n)!=sphi.end()) return sphi[n];
LL res=n*(n+1)>>1;
for (LL l=2,r;l<=n;l=r+1){
r=n/(n/l);
res-=(r-l+1)*Get_sumphi(n/l);
}
return sphi[n]=res;
}
int Get_summu(LL n){
if (n<=M) return mu[n];
if (smu.find(n)!=smu.end()) return smu[n];
int res=1;
for (LL l=2,r;l<=n;l=r+1){
r=n/(n/l);
res-=(r-l+1)*Get_summu(n/l);
}
return smu[n]=res;
}
void work(){
ans0=Get_sumphi(n);
ans1=Get_summu(n);
}
void outo(){
printf("%lld %lld\n",ans0,ans1);
}
int main(){
int T;
scanf("%d",&T);
start();
for (;T--;){
into();
work();
outo();
}
return 0;
}