神奇函数
题意
- 就是求上面那个式子 233 233 233
题解
- 第一次写这种看上去像积性函数的题目,简单记录一下
- 首先考虑把那个递推的式子转化成容易理解的式子,从
x
x
x往前每次除以一个最小的质因子的平方或者这个最小质因子,很容易发现这样一个规律,如果将
x
x
x表示为
x = p 1 t 1 × p 2 t 2 × p 3 t 3 × . . . × p n t n x=p_1^{t_1}\times p_2^{t_2} \times p_3^{t_3}\times ...\times p_n^{t_n} x=p1t1×p2t2×p3t3×...×pntn
那么
f ( x ) = p 1 t 1 2 × p 2 t 2 2 × p 3 t 3 2 × . . . × p n t n 2 f(x)=p_1^{\frac{t_1}{2}}\times p_2^{\frac{t_2}{2}} \times p_3^{\frac{t_3}{2}}\times ...\times p_n^{\frac{t_n}{2}} f(x)=p12t1×p22t2×p32t3×...×pn2tn
然后有欧拉函数的性质可知
n = ∑ d ∣ n p h i ( d ) n=\sum_{d|n}phi(d) n=d∣n∑phi(d)
n n n换成 f ( x ) f(x) f(x)
f ( x ) = ∑ d ∣ f ( x ) p h i ( d ) f(x)=\sum_{d|f(x)}{phi(d)} f(x)=d∣f(x)∑phi(d)
右边有个 f ( x ) f(x) f(x)考虑换成 n n n
f ( x ) = ∑ d 2 ∣ n p h i ( d ) f(x)=\sum_{d^2|n}{phi(d)} f(x)=d2∣n∑phi(d)
所以题目需要求的
∑
i
=
1
n
f
[
i
]
=
∑
i
=
1
n
∑
d
2
∣
i
p
h
i
[
d
]
=
∑
d
=
1
d
2
≤
n
∑
i
=
1
n
d
2
p
h
i
[
d
]
=
∑
d
=
1
d
2
≤
n
n
d
2
p
h
i
[
d
]
\sum_{i=1}^{n}{f[i]}=\sum_{i=1}^{n}{\sum_{d^2|i}^{}{phi[d]}} =\sum_{d=1}^{d^2\leq n}{\sum_{i=1}^{\frac{n}{d^2}}{phi[d]}}= \sum_{d=1}^{d^2\leq n}{\frac{n}{d^2}phi[d]}
i=1∑nf[i]=i=1∑nd2∣i∑phi[d]=d=1∑d2≤ni=1∑d2nphi[d]=d=1∑d2≤nd2nphi[d]
线筛欧拉函数然后
O
(
n
)
O(\sqrt{n})
O(n)统计答案即可
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e6;
long long n;
int phi[maxn+10],prime[maxn+10],tot,ans;
bool mark[maxn+10];
void getphi()
{
phi[1]=1;
for(int i=2;i<=maxn;i++)
{
if(!mark[i]) {
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++){
if(i*prime[j]>maxn) break;
mark[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);
}
}
}
int main()
{
getphi();
int t;scanf("%d",&t);
while(t--) {
scanf("%lld",&n);long long ans=0;
for(long long i=1;i*i<=n;i++) ans+=(n/(i*i))*phi[i];
printf("%lld\n",ans);
}
}