% 给定 n n n,求 ∑ i = 1 n ∑ j = 1 n d ( gcd ( i , j ) ) \sum_{i=1}^n\sum_{j=1}^nd(\gcd(i,j)) i=1∑nj=1∑nd(gcd(i,j))
对 1 0 9 + 7 10^9+7 109+7 取模的结果,其中 d ( x ) d(x) d(x) 表示 x x x 的约数个数。
数据范围 1 ⩽ n ⩽ 1 0 12 1\leqslant n\leqslant 10^{12} 1⩽n⩽1012
% 先枚举 x = gcd ( i , j ) x=\gcd(i,j) x=gcd(i,j),然后莫比乌斯反演常规套路。
∑ i = 1 n ∑ j = 1 n d ( ( i , j ) ) = ∑ x = 1 n ∑ i = 1 n ∑ j = 1 n d ( x ) [ ( i , j ) = x ] = ∑ x = 1 n ∑ i = 1 n x ∑ j = 1 n x d ( x ) ∑ d ∣ ( i , j ) μ ( d ) = ∑ x = 1 n d ( x ) ∑ i = 1 n x ∑ j = 1 n x ∑ d ∣ ( i , j ) μ ( d ) = ∑ x = 1 n d ( x ) ∑ d = 1 n μ ( d ) ⌊ n d x ⌋ 2 = ∑ i = 1 n ⌊ n i ⌋ 2 ∑ d ∣ i d ( i d ) μ ( d ) = ∑ i = 1 n ⌊ n i ⌋ 2 ( d ∗ μ ) ( i ) \begin{aligned}\sum_{i=1}^n\sum_{j=1}^nd((i,j)) &=\sum_{x=1}^n\sum_{i=1}^n\sum_{j=1}^nd(x)[(i,j)=x]\\ &=\sum_{x=1}^n\sum_{i=1}^{\frac nx}\sum_{j=1}^{\frac nx}d(x)\sum_{d|(i,j)}\mu(d)\\ &=\sum_{x=1}^nd(x)\sum_{i=1}^{\frac nx}\sum_{j=1}^{\frac nx}\sum_{d|(i,j)}\mu(d)\\ &=\sum_{x=1}^nd(x)\sum_{d=1}^n\mu(d)\lfloor\frac n{dx}\rfloor^2\\ &=\sum_{i=1}^n\lfloor\frac n{i}\rfloor^2\sum_{d|i} d(\frac id)\mu(d)\\ &=\sum_{i=1}^n\lfloor\frac n{i}\rfloor^2(d*\mu)(i)\\ \end{aligned} i=1∑nj=1∑nd((i,j))=x=1∑ni=1∑nj=1∑nd(x)[(i,j)=x]=x=1∑ni=1∑xnj=1∑xnd(x)d∣(i,j)∑μ(d)=x=1∑nd(x)i=1∑xnj=1∑xnd∣(i,j)∑μ(d)=x=1∑nd(x)d=1∑nμ(d)⌊dxn⌋2=i=1∑n⌊in⌋2d∣i∑d(di)μ(d)=i=1∑n⌊in⌋2(d∗μ)(i)
% 考虑到对于常函数 1 ( n ) = 1 1(n)=1 1(n)=1 和单位函数 ϵ ( n ) = [ n = 1 ] \epsilon(n)=[n=1] ϵ(n)=[n=1],有 1 ∗ μ = ϵ , 1 ∗ 1 = d 1*\mu=\epsilon,1*1=d 1∗μ=ϵ,1∗1=d,因而
( d ∗ μ ) ( i ) = ( 1 ∗ 1 ∗ μ ) ( i ) = ( 1 ∗ ϵ ) ( i ) = 1 ( i ) = 1 (d*\mu)(i)=(1*1*\mu)(i)=(1*\epsilon)(i)=1(i)=1 (d∗μ)(i)=(1∗1∗μ)(i)=(1∗ϵ)(i)=1(i)=1
% 因此有 ∑ i = 1 n ∑ j = 1 n d ( ( i , j ) ) = ∑ i = 1 n ⌊ n i ⌋ 2 \sum_{i=1}^n\sum_{j=1}^nd((i,j))=\sum_{i=1}^n\lfloor\frac n{i}\rfloor^2 i=1∑nj=1∑nd((i,j))=i=1∑n⌊in⌋2
% 直接除法分块即可。
% 由于 n n n 的范围比较大,需要注意除法分块过程中不要忘记取模。
#include
using namespace std;
const long long mod=1000000007;
#define int long long
signed main(){
int n,T;
scanf("%lld",&T);
while(T--&&~scanf("%lld",&n)){
int ans=0;
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);
ans+=((n/l)%mod)*((n/l)%mod)%mod*((r-l+1+mod)%mod)%mod;
ans%=mod;
}
printf("%lld\n",ans%mod);
}
return 0;
}