一通套路后得Σφ(d)μ(D/d)⌊n/D⌋2。显然整除分块,问题在于怎么快速计算φ和μ的狄利克雷卷积。积性函数的卷积还是积性函数,那么线性筛即可。因为μ(pc)=0 (c>=2),所以f(pc)还是比较好算的,讨论一波即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 10000001 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int T,n,phi[N],mobius[N],prime[N],cnt; ll f[N]; bool flag[N]; int main() { #ifndef ONLINE_JUDGE freopen("bzoj4804.in","r",stdin); freopen("bzoj4804.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #endif T=read(); flag[1]=1;mobius[1]=1;phi[1]=1;f[1]=1; for (int i=1;i<N;i++) { if (!flag[i]) prime[++cnt]=i,phi[i]=i-1,mobius[i]=-1,f[i]=i-2; for (int j=1;j<=cnt&&prime[j]*i<N;j++) { flag[prime[j]*i]=1; if (i%prime[j]==0) { phi[prime[j]*i]=phi[i]*prime[j]; if ((i/prime[j])%prime[j]) f[prime[j]*i]=f[i/prime[j]]*(1ll*prime[j]*prime[j]-2*prime[j]+1); else f[prime[j]*i]=f[i]*prime[j]; break; } mobius[prime[j]*i]=-mobius[i]; phi[prime[j]*i]=phi[i]*(prime[j]-1); f[prime[j]*i]=f[i]*(prime[j]-2); } } for (int i=1;i<N;i++) f[i]+=f[i-1]; while (T--) { n=read();ll ans=0; for (int i=1;i<=n;i++) { int t=n/(n/i); ans+=(f[t]-f[i-1])*(n/i)*(n/i); i=t; } printf(LL,ans); } return 0; }