这题一开始我竟然想要用与能量采集差不多的思路去做= =(no zuo no die,why you try?)
有个显然的转化
∑nx=1∑ny=1[gcd(x,y)==P]=∑⌊n/P⌋x=1∑⌊n/P⌋y=1[gcd(x,y)==1]=2∗∑⌊n/P⌋i=2ϕ(i)+1
然后我们线性筛出欧拉函数,在前缀和就可以O(n)求出答案了
code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[10000001];
int phi[10000001],p[700001];
long long ans=0;
long long s[10000001];
int a[10000001],n;
int main()
{
long long i,t=0,j;
scanf("%lld",&n);
a[1]=1; phi[1]=1;
for (i=2;i<=n;++i)
{
if (!a[i])
{
p[++t]=i;
phi[i]=i-1;
}
for (j=1;j<=t;++j)
{
if (i*p[j]>n) break;
a[i*p[j]]=1;
if (i%p[j]==0)
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
else
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
s[1]=0;
for (i=2;i<=n;++i) s[i]=s[i-1]+phi[i];
for (i=1;i<=n;++i) f[i]=2*s[i]+1;
for (i=1;i<=t;++i) ans=ans+f[n/p[i]];
printf("%lld\n",ans);
}
本文深入探讨了一个复杂的数学问题,通过巧妙地转换和应用欧拉函数,揭示了解决该问题的高效算法。利用线性筛法计算欧拉函数,并结合前缀和技巧,实现了O(n)的时间复杂度求解。此方法不仅简洁明了,而且在实际应用中展现出卓越的性能。
456

被折叠的 条评论
为什么被折叠?



