设
f
[
d
]
=
∑
∑
gcd
(
i
,
j
)
=
d
,
F
[
d
]
=
∑
∑
d
∣
gcd
(
i
,
j
)
f[d]=\sum\sum \gcd(i,j)=d,F[d]=\sum\sum d|\gcd(i,j)
f[d]=∑∑gcd(i,j)=d,F[d]=∑∑d∣gcd(i,j)
不难看出
F
[
d
]
=
(
n
/
d
)
2
F[d]=(n/d)^2
F[d]=(n/d)2
那么
f
[
d
]
=
F
[
d
]
−
∑
f
[
k
d
]
f[d]=F[d]-∑f[kd]
f[d]=F[d]−∑f[kd]
通过枚举
d
d
d 的方式,我们可以求出
∑
i
=
1
n
∑
j
=
1
n
gcd
(
i
,
j
)
\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(i,j)
i=1∑nj=1∑ngcd(i,j)
然后稍作处理就是题目要求的答案了。
好像很简单的样子啊qwq
所以倒着
O
(
n
log
n
)
\mathcal{O(n\log n)}
O(nlogn) 扫一遍就珂以了QAQ
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long //不开ll见祖宗
using namespace std;
ll f[2000010];
int main() {
ll n,ans=0;
scanf("%lld",&n);
for (int i=n; i>=1; --i) { //枚举d
f[i]=(n/i)*(n/i);
for (int j=(i<<1); j<=n; j+=i) { //枚举kd
f[i]-=f[j];
}
ans+=(ll)(f[i]*i);
}
ans=ans-n*(n+1)/2; //除去gcd(i,i)形式的结果
ans/=2; //除去重复部分
printf("%lld\n",ans);
return 0;
}