(sumlimits_{i=1}^{n}lcm(i,n))
(=sumlimits_{i=1}^{n}dfrac{i imes n}{gcd(i,n)})
(=n imessumlimits_{d|n}sumlimits_{i=1}^{n}dfrac{i}{d} [gcd(i,n)=d])
同除以(d),设(i=)原来的(i/d)
(=n imessumlimits_{d|n}sumlimits_{i=1}^{frac{n}{d}}i [gcd(i,frac{n}{d})=1])
因为(gcd(n,i)=gcd(n,n-i)),即若(i)与(n)互质,则(n-i)也与(n)互质。
所以,((1,n))中,与(n)互质的数的总和为 (dfrac{varphi(n)*n}{2})
(=n imessumlimits_{d|n} dfrac{varphi(frac{n}{d})*frac{n}{d}}{2})
枚举(d)反过来相当于枚举(dfrac{n}{d})
(=n imessumlimits_{d|n} dfrac{varphi(d)*d}{2})
预处理出(varphi(i)),利用类似埃氏筛的筛法,用每个数更新它的倍数。复杂度(O(nlogn))。
code
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;
const int maxn = 1e6+10;
const int N = 1e6;
int t,prime[maxn],phi[maxn],cnt;
long long n,sum[maxn];
bool vis[maxn];
void Phi() {
phi[1] = 1;
for(int i = 2; i <= N; i++) {
if(!vis[i]) {
prime[++cnt] = i;
phi[i] = i-1;
}
for(int j = 1; j <= cnt && i*prime[j] <= N; j++) {
vis[i*prime[j]] = true;
if(i % prime[j])
phi[i*prime[j]] = phi[i] * (prime[j]-1);
else {
phi[i*prime[j]] = phi[i] * prime[j];
break;
}
}
}
}
void solve() {
for(long long i = 1; i <= N; i++)
for(long long j = 1; i*j <= N; j++) {
if(i == 1) sum[i*j] += 1;
else sum[i*j] += phi[i]*i/2;
}
}
int main() {
scanf("%d",&t);
Phi();
solve();
while(t--) {
scanf("%lld",&n);
printf("%lld
",sum[n]*n);
}
return 0;
}