令
A(n)=n∑i=1ni(i,n)
=n∑d|n∑i=1ndi[(i,nd)=1]
=n∑d|ndφ(d)+n
那么
Ans=2A(n)−∑i=1ni
=∑i=1ni∑d|idφ(d)
=∑d=1nd2φ(d)∑i=1⌊nd⌋i
∑nd=1d2φ(d) 这个东西可以用杜教筛推
p(n)=∑i=1ni2φ(i)
∑i=1n∑d|id2φ(d)(id)2=∑i=1ni3=∑i=1ni2p(⌊ni⌋)
杜教筛一下就好了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int N=10000010,P=1e9+7;
int p[N],phi[N];
ll S[N];
inline void Pre(){
phi[1]=1;
for(int i=2;i<=10000000;i++){
if(!p[i]) p[++*p]=i,phi[i]=i-1;
for(int j=1;j<=*p && 1LL*i*p[j]<=10000000;j++){
p[i*p[j]]=1;
if(i%p[j]) phi[i*p[j]]=phi[i]*(p[j]-1);
else{
phi[i*p[j]]=phi[i]*p[j];
break;
}
}
}
for(int i=1;i<=10000000;i++)
S[i]=(S[i-1]+1LL*i*i%P*phi[i])%P;
}
const ll inv2=P+1>>1,inv=(P+1)/6;
inline ll SS(ll l,ll r){
return (r-l+1)%P*((l+r)%P)%P*inv2%P;
}
inline ll Sqr(ll n){
n%=P;
return n*(n+1)%P*(2*n+1)%P*inv%P;
}
inline ll SqrS(ll l,ll r){
return (Sqr(r)-Sqr(l-1))%P;
}
map<ll,ll> M;
inline ll Cube(ll n){
return SS(1,n)*SS(1,n)%P;
}
ll Sum(ll n){
if(n<=10000000) return S[n];
if(M.count(n)) return M[n];
ll ret=Cube(n);
for(ll i=2,j;i<=n;i=j+1){
j=n/(n/i);
ret=(ret-SqrS(i,j)*Sum(n/i))%P;
}
return M[n]=ret;
}
int main(){
ll n,ans=0;
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%lld",&n); Pre();
for(ll i=1,j,lst=0;i<=n;i=j+1){
j=n/(n/i); ll cur=Sum(j);
ans=(ans+SS(1,n/i)*(cur-lst))%P;
lst=cur;
}
printf("%lld\n",(ans+P)%P);
return 0;
}