南昌网络赛tsy’s number(莫比乌斯反演&线性递推)
题目大意
给出n,求
∑
i
=
1
n
∑
j
=
1
n
∑
j
=
1
n
φ
(
i
)
φ
(
j
2
)
φ
(
k
3
)
φ
(
i
)
φ
(
j
)
φ
(
k
)
φ
(
g
c
d
(
i
,
j
,
k
)
)
\sum_{i=1}^n\sum_{j=1}^n\sum_{j=1}^n{\varphi(i)\varphi(j^2)\varphi(k^3)\over\varphi(i)\varphi(j)\varphi(k)}\varphi(gcd(i,j,k))
i=1∑nj=1∑nj=1∑nφ(i)φ(j)φ(k)φ(i)φ(j2)φ(k3)φ(gcd(i,j,k))
解题思路
据欧拉函数的性质,原式可以化作
∑
i
=
1
n
∑
j
=
1
n
∑
k
=
1
n
j
k
2
φ
(
g
c
d
(
i
,
j
,
k
)
)
\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^njk^2\varphi(gcd(i,j,k))
i=1∑nj=1∑nk=1∑njk2φ(gcd(i,j,k))
也就可以化作
∑
d
=
1
n
∑
i
=
1
n
∑
j
=
1
n
∑
k
=
1
n
j
k
2
φ
(
d
)
[
g
c
d
(
i
,
j
,
k
)
=
=
d
]
→
∑
d
=
1
n
d
3
φ
(
d
)
∑
i
=
1
[
n
d
]
∑
j
=
1
[
n
d
]
∑
k
=
1
[
n
d
]
j
k
2
[
g
c
d
(
i
,
j
,
k
)
=
=
1
]
\sum_{d=1}^n\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^njk^2\varphi(d)[gcd(i,j,k)==d]\\ \rightarrow\sum_{d=1}^nd^3\varphi(d)\sum_{i=1}^{[{n\over d}]}\sum_{j=1}^{[{n\over d}]}\sum_{k=1}^{[{n\over d}]}jk^2[gcd(i,j,k)==1]
d=1∑ni=1∑nj=1∑nk=1∑njk2φ(d)[gcd(i,j,k)==d]→d=1∑nd3φ(d)i=1∑[dn]j=1∑[dn]k=1∑[dn]jk2[gcd(i,j,k)==1]
令一新的函数为
f
(
s
)
=
∑
i
=
1
[
n
d
]
∑
j
=
1
[
n
d
]
∑
k
=
1
[
n
d
]
j
k
2
[
g
c
d
(
i
,
j
,
k
)
=
=
s
]
f(s)=\sum_{i=1}^{[{n\over d}]}\sum_{j=1}^{[{n\over d}]}\sum_{k=1}^{[{n\over d}]}jk^2[gcd(i,j,k)==s]
f(s)=i=1∑[dn]j=1∑[dn]k=1∑[dn]jk2[gcd(i,j,k)==s]
再令一
F
(
s
)
=
∑
s
∣
d
f
(
d
)
F(s)=\sum_{s|d}f(d)
F(s)=∑s∣df(d)
则
F
(
s
)
F(s)
F(s)可以写作
F
(
s
)
=
∑
i
=
1
[
n
d
]
∑
j
=
1
[
n
d
]
∑
k
=
1
[
n
d
]
j
k
2
[
s
∣
g
c
d
(
i
,
j
,
k
)
]
→
=
s
3
∑
i
=
1
[
n
s
d
]
∑
i
=
1
[
n
s
d
]
∑
i
=
1
[
n
s
d
]
j
k
2
[
1
∣
g
c
d
(
i
,
j
,
k
)
]
→
=
s
3
∑
i
=
1
[
n
s
d
]
∑
i
=
1
[
n
s
d
]
∑
i
=
1
[
n
s
d
]
j
k
2
F(s)=\sum_{i=1}^{[{n\over d}]}\sum_{j=1}^{[{n\over d}]}\sum_{k=1}^{[{n\over d}]}jk^2[s|gcd(i,j,k)]\\ \rightarrow=s^3\sum_{i=1}^{[{n\over sd}]}\sum_{i=1}^{[{n\over sd}]}\sum_{i=1}^{[{n\over sd}]}jk^2[1|gcd(i,j,k)] \\\rightarrow=s^3\sum_{i=1}^{[{n\over sd}]}\sum_{i=1}^{[{n\over sd}]}\sum_{i=1}^{[{n\over sd}]}jk^2
F(s)=i=1∑[dn]j=1∑[dn]k=1∑[dn]jk2[s∣gcd(i,j,k)]→=s3i=1∑[sdn]i=1∑[sdn]i=1∑[sdn]jk2[1∣gcd(i,j,k)]→=s3i=1∑[sdn]i=1∑[sdn]i=1∑[sdn]jk2
据莫比乌斯反演
f
(
s
)
=
∑
s
∣
d
μ
(
d
s
)
F
(
d
)
f(s)=\sum_{s|d}\mu(\frac{d}{s})F(d)
f(s)=∑s∣dμ(sd)F(d)
原式就可以化成
=
∑
d
=
1
n
φ
(
d
)
d
3
∑
t
=
1
[
n
d
]
μ
(
t
)
t
3
∑
i
=
1
[
n
t
d
]
∑
i
=
1
[
n
t
d
]
∑
i
=
1
[
n
t
d
]
j
k
2
=\sum_{d=1}^n\varphi(d)d^3\sum_{t=1}^{[{n\over d}]}\mu(t)t^3\sum_{i=1}^{[{n\over td}]}\sum_{i=1}^{[{n\over td}]}\sum_{i=1}^{[{n\over td}]}jk^2\\
=d=1∑nφ(d)d3t=1∑[dn]μ(t)t3i=1∑[tdn]i=1∑[tdn]i=1∑[tdn]jk2
再令
T
=
t
d
T=td
T=td将式子转化就有
a
n
s
[
n
]
=
∑
T
=
1
n
T
3
∑
d
∣
T
φ
(
d
)
μ
(
T
d
)
∑
i
=
1
[
n
t
d
]
∑
i
=
1
[
n
t
d
]
∑
i
=
1
[
n
t
d
]
j
k
2
ans[n]=\sum_{T=1}^nT^3\sum_{d|T}\varphi(d)\mu({T\over d})\sum_{i=1}^{[{n\over td}]}\sum_{i=1}^{[{n\over td}]}\sum_{i=1}^{[{n\over td}]}jk^2
ans[n]=T=1∑nT3d∣T∑φ(d)μ(dT)i=1∑[tdn]i=1∑[tdn]i=1∑[tdn]jk2
其中
∑
i
=
1
[
n
t
d
]
∑
i
=
1
[
n
t
d
]
∑
i
=
1
[
n
t
d
]
j
k
2
\sum_{i=1}^{[{n\over td}]}\sum_{i=1}^{[{n\over td}]}\sum_{i=1}^{[{n\over td}]}jk^2
∑i=1[tdn]∑i=1[tdn]∑i=1[tdn]jk2可以整除分块得到答案
而 ∑ d ∣ T φ ( d ) μ ( T d ) \sum_{d|T}\varphi(d)\mu({T\over d}) ∑d∣Tφ(d)μ(dT)可以通过线性递推得到
令 g ( d ) = ∑ i ∣ d φ ( i ) μ ( d i ) g(d)=\sum_{i|d}\varphi(i)\mu({d\over i}) g(d)=∑i∣dφ(i)μ(id)
根据欧拉函数与莫比乌斯函数的性质,我们可以进行如下分类
当d为素数时易证 g ( d ) = d − 2 g(d)=d-2 g(d)=d−2
当d为合数时:
设d由 q ∗ p q*p q∗p(p为素数,q为合数)递推来
g ( d ) g(d) g(d)可以写作 g ( d ) = ∑ i ∣ q φ ( i p ) μ ( q i ) + ∑ i ∣ q φ ( i ) μ ( q p i ) g(d)=\sum_{i|q}\varphi(ip)\mu({q\over i})+\sum_{i|q}\varphi(i)\mu({qp\over i}) g(d)=∑i∣qφ(ip)μ(iq)+∑i∣qφ(i)μ(iqp)
设 A ( d ) = ∑ i ∣ q φ ( i p ) μ ( q i ) A(d)=\sum_{i|q}\varphi(ip)\mu({q\over i}) A(d)=∑i∣qφ(ip)μ(iq), B ( d ) = ∑ i ∣ q φ ( i ) μ ( q p i ) B(d)=\sum_{i|q}\varphi(i)\mu({qp\over i}) B(d)=∑i∣qφ(i)μ(iqp)
当q与p互素时:
由于欧拉函数为积性函数因此 A ( d ) = φ ( p ) ∗ A ( q ) A(d)=\varphi(p)*A(q) A(d)=φ(p)∗A(q)
由于增加了一个互素的素因子,因此所有的莫比乌斯函数取相反数 B ( d ) = − A ( q ) B(d)=-A(q) B(d)=−A(q)
(或根据g(d)为欧拉函数与莫比乌斯函数的迪利克雷卷积,可以得其也为积性函数)
当p为q的因数时:
由于qp种有重复因数,根据莫比乌斯函数 B ( d ) = 0 B(d)=0 B(d)=0
设 q = o ∗ P m q=o*P^m q=o∗Pm
当
m
=
=
1
m==1
m==1时
A
(
d
)
=
∑
i
∣
o
φ
(
i
p
)
μ
(
o
p
i
)
+
∑
i
∣
o
φ
(
i
p
2
)
μ
(
o
i
)
→
=
−
∑
i
∣
o
φ
(
i
p
)
μ
(
o
i
)
+
p
∑
i
∣
o
φ
(
i
p
)
μ
(
o
i
)
→
=
(
p
−
1
)
∗
∑
i
∣
o
φ
(
i
p
)
μ
(
o
i
)
→
=
(
p
−
1
)
∗
p
h
i
(
p
)
∗
∑
i
∣
o
φ
(
i
)
μ
(
o
i
)
→
=
(
p
−
1
)
∗
p
h
i
(
p
)
∗
g
[
o
]
A(d)=\sum_{i|o}\varphi(ip)\mu(\frac{op}{i})+\sum_{i|o}\varphi(ip^2)\mu(\frac{o}{i}) \\\rightarrow=-\sum_{i|o}\varphi(ip)\mu(\frac{o}{i})+p\sum_{i|o}\varphi(ip)\mu(\frac{o}{i}) \\\rightarrow=(p-1)*\sum_{i|o}\varphi(ip)\mu({o\over i}) \\\rightarrow=(p-1)*phi(p)*\sum_{i|o}\varphi(i)\mu({o\over i}) \\\rightarrow=(p-1)*phi(p)*g[o]
A(d)=i∣o∑φ(ip)μ(iop)+i∣o∑φ(ip2)μ(io)→=−i∣o∑φ(ip)μ(io)+pi∣o∑φ(ip)μ(io)→=(p−1)∗i∣o∑φ(ip)μ(io)→=(p−1)∗phi(p)∗i∣o∑φ(i)μ(io)→=(p−1)∗phi(p)∗g[o]
当 m ≥ 2 m\ge2 m≥2时
由于欧拉函数的性质 φ ( q p ) = φ ( q ) ∗ p \varphi(qp)=\varphi(q)*p φ(qp)=φ(q)∗p
因此 A ( d ) = p ∗ g [ q ] A(d)=p*g[q] A(d)=p∗g[q]
由此线性递推出所有的答案即可
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e7+5;
const LL mod=1<<30;
bool check[maxn];
int prime[maxn];
int g[maxn];
int f[maxn];
int phi[maxn];
int tot=0;
int sum[maxn];
void init()
{
for(int i=1;i<maxn;i++)
{
f[i]=i;
}
for(int i=1;i<maxn;i++)
{
g[i]=(1LL*g[i-1]+1LL*i)%mod;
f[i]=(1LL*f[i]*g[i])%mod;
}
for(int i=1;i<maxn;i++)
{
g[i]=(1LL*g[i-1]+1LL*i*i)%mod;
f[i]=(1LL*f[i]*g[i])%mod;
}
g[1]=phi[1]=1;
for(int i=2;i<maxn;i++) check[i]=true;
for(int i=2;i<maxn;i++)
{
if(check[i])
{
phi[i]=i-1;
prime[tot++]=i;
g[i]=i-2;//for mu(1)=1
}
for(int j=0;j<tot&&prime[j]*i<maxn;j++)
{
check[i*prime[j]]=false;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
if((i/prime[j])%prime[j]==0) g[i*prime[j]]=g[i]*prime[j]%mod;
else g[i*prime[j]]=(prime[j]-1)*phi[prime[j]]*g[i/prime[j]];
break;
}
else
{
phi[i*prime[j]]=phi[i]*phi[prime[j]];
g[i*prime[j]]=((-g[i]+1LL*phi[prime[j]]*g[i])%mod+mod)%mod;
}
}
}
for(int i=1;i<maxn;i++)
{
sum[i]=(sum[i-1]+((((1LL*g[i]*i%mod)*i)%mod)*i)%mod)%mod;
}
}
int solve(int n)
{
int ans=0;
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
ans=(ans+((((sum[r]-sum[l-1])%mod+mod)%mod)*f[n/l])%mod)%mod;
}
return ans;
}
int main()
{
int t;
init();
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
printf("%d\n",solve(n));
}
}