这题一开始我竟然想要用与能量采集差不多的思路去做= =(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
#include
#include
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);
}