设 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)2F[d]=(n/d)^2F[d]=(n/d)2
那么 f[d]=F[d]−∑f[kd]f[d]=F[d]-∑f[kd]f[d]=F[d]−∑f[kd]
通过枚举 ddd 的方式,我们可以求出 ∑i=1n∑j=1ngcd(i,j)\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(i,j)i=1∑nj=1∑ngcd(i,j)
然后稍作处理就是题目要求的答案了。
好像很简单的样子啊qwq
所以倒着 O(nlogn)\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;
}