http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1220
$G(n)=sumlimits_{i=1}^nsumlimits_{j=1}^nsumlimits_{k=1}^{n^2}[k|ij]cdot k$
$ small{[k|ij] o[frac{k}{gcd(i,k)}|j]}$
$G(n)=sumlimits_{i=1}^nsumlimits_{j=1}^nsumlimits_{k=1}^{n^2}[frac{k}{gcd(i,k)}|j]cdot k$
$ small{gcd(i,k) o g,i/g o i,sumlimits_{j=1}^X[Y|j] o lfloorfrac XY
floor}$
$G(n)=sumlimits_{k=1}^{n^2}sumlimits_{g|k}sumlimits_{i=1}^{n/g}[gcd(i,k/g)=1]lfloorfrac{n}{k/g}
floorcdot k$
$ small{k/g o k}$
$G(n)=sumlimits_{g=1}^{n}sumlimits_{k=1}^{n}sumlimits_{i=1}^{n/g}[gcd(i,k)=1]lfloorfrac{n}{k}
floorcdot kcdot g$
$small{[X=1] osumlimits_{d|X}mu(d)}$
$G(n)=sumlimits_{g=1}^{n}sumlimits_{k=1}^{n}sumlimits_{i=1}^{n/g}sumlimits_{d|iwedge d|k}mu(d)lfloorfrac{n}{k}
floorcdot kcdot g$
$small{i/d o i,k/d o k}$
$G(n)=sumlimits_{d=1}^nsumlimits_{g=1}^{n/d}sumlimits_{k=1}^{n/d}sumlimits_{i=1}^{n/gd}mu(d)lfloorfrac{n}{kd}
floorcdot kcdot gcdot d$
$small{sumlimits_{i=1}^X1 o X}$
$G(n)=sumlimits_{d=1}^nsumlimits_{g=1}^{n/d}sumlimits_{k=1}^{n/d}mu(d)lfloorfrac{n}{gd}
floorlfloorfrac{n}{kd}
floorcdot kcdot gcdot d$
$small{ig(sumlimits_{i=1}^{n}ilfloorfrac{n}{d}
floorig)^2 o F(n)}$
$G(n)=sumlimits_{d=1}^nmu(d)dcdot F(lfloorfrac{n}{d}
floor)$
$small{G o sum g,F o sum f}$
$g(n)=sum limits_{d|n}mu(d)dcdot f(n/d)$
$f(n)=sum limits_{d|n}dcdot g(n/d)$
$small{sum f o F,sum g o G}$
$F(n)=sumlimits_{d=1}^ndcdot G(lfloorfrac{n}{d}
floor)$
$G(n)=F(n)-sumlimits_{d=2}^ndcdot G(lfloorfrac{n}{d}
floor)$
记录一下推公式过程。
最后用记忆化搜索就可以$O(n^{3/4})$过了,如果加上线性预处理可以做到$O(n^{2/3})$
#include<bits/stdc++.h> typedef unsigned long long i64; const int P=1e9+7; int n,vG[32007],vg[32007],B; int G(int n){ int&ans=n<=B?vg[n]:vG[::n/n]; if(ans)return ans; i64 s=0,sx=n*2; for(int l=1,r,c;l<n;l=r){ r=n/(c=n/(l+1)); i64 t=i64(r+l+1)*(r-l); sx+=t*c; s+=t%P*G(c); if(s>i64(1.5e19))s%=P; } sx=sx/2%P; s=(sx*sx%P-s%P*((P+1)/2)%P+P)%P; return ans=s; } int main(){ scanf("%d",&n); B=sqrt(n); printf("%d ",G(n)); return 0; }