Description
Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the integers i and n.
1 <= T <= 300000
1 <= n <= 1000000
Solution
刷水题有益身心健康~
ans=n∑d|n∑i=1ndi[gcd(nd,i)=1]ans=n∑d|n∑i=1ndi[gcd(nd,i)=1]
等同于
n∑d|n12φ(d)dn∑d|n12φ(d)d
其实最开始的时候yy了一下gcd=1那里套一个μ的,感受了一下似乎能做惹
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int N=1000005;
int phi[N+1],prime[N/10];
bool not_prime[N+1];
void pre_work() {
phi[1]=1;
rep(i,2,N) {
if (!not_prime[i]) {
prime[++prime[0]]=i;
phi[i]=i-1;
}
for (int j=1;i*prime[j]<=N&&j<=prime[0];j++) {
not_prime[i*prime[j]]=1;
if (i%prime[j]==0) {
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
void solve(int n) {
LL ans=0;
for (int i=1;i*i<=n;i++) {
if (n%i) continue;
if (i==1) ans+=1;
else ans=ans+(LL)i*(LL)phi[i]/2;
if (i*i!=n) ans=ans+(LL)(n/i)*(LL)phi[n/i]/2;
}
ans=ans*n;
printf("%lld\n", ans);
}
int main(void) {
pre_work();
int T; scanf("%d",&T);
while (T--) {
int n; scanf("%d",&n);
solve(n);
}
return 0;
}