$\sum_{i=1}^{n}\sum_{j=1}^{n}gcd(i,j)\\$

$=\sum_{d=1}^{n}d\sum_{i=1}^{n/d}\sum_{j=1}^{n/d}\varepsilon(gcd(i,j))$

$=\sum_{d=1}^{n}d\sum_{g=1}^{n/d}\mu(g)\cdot (n/d/t)^{2}$

$=\sum_{T=1}^{n}(n/T)^{2}\sum_{d|T}\mu(T/d)\cdot d$

$=\sum_{T=1}^{n}(n/T)^2\cdot \varphi(T)$

对其数论分块,即求一段区间内$\varphi$的和,可以用杜教筛来做

设$f(i)=\sum_{j=1}^{i}\varphi(j)$,根据$\varphi*I=id$,即$f(n)=(n+1)n/2-\sum_{i=2}^{n}f(n/i)$

[51nod1237]最大公约数之和V3_数学-杜教筛[51nod1237]最大公约数之和V3_#define_02
 1 #include<bits/stdc++.h> 
 2 #include<tr1/unordered_map>
 3 using namespace std;
 4 #define ll long long
 5 #define mod 1000000007
 6 #define N 5000005
 7 tr1::unordered_map<ll,ll>mat;
 8 ll n,ans,cp[N],vis[N],p[N];
 9 ll djs(ll n){
10     if (n<=N-5)return cp[n];
11     if (mat[n])return mat[n];
12     ll ans=n%mod*((n+1)%mod)%mod*(mod/2+1)%mod;
13     for(ll i=2,j;i<=n;i=j+1){
14         j=n/(n/i);
15         ans=(ans-(j-i+1)%mod*djs(n/i)%mod+mod)%mod;
16     }
17     return mat[n]=ans;
18 }
19 int main(){
20     scanf("%lld",&n);
21     cp[1]=1;
22     for(int i=2;i<=N-5;i++){
23         if (!vis[i])cp[p[++p[0]]=i]=i-1;
24         for(int j=1;j<=p[0];j++){
25             if (i*p[j]>N-5)break;
26             vis[i*p[j]]=1;
27             if (i%p[j])cp[i*p[j]]=cp[i]*(p[j]-1);
28             else{
29                 cp[i*p[j]]=cp[i]*p[j];
30                 break;
31             }
32         }
33     }
34     for(int i=2;i<=N-5;i++)cp[i]=(cp[i]+cp[i-1])%mod;
35     for(ll i=1,j;i<=n;i=j+1){
36         j=n/(n/i);
37         ans=(ans+(djs(j)-djs(i-1)+mod)%mod*(n/i%mod)%mod*(n/i%mod))%mod;
38     }
39     printf("%lld",ans);
40 }
View Code