$\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)$
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