http://www.elijahqi.win/archives/2951
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.
Input
The first line contains T the number of test cases. Each of the next T lines contain an integer n.
Output
Output T lines, one for each test case, containing the required sum.
Sample Input
3
1
2
5
Sample Output
1
4
55
HINT
Constraints
1 <= T <= 300000
1 <= n <= 1000000
题意简述
∑ni=1lcm(i,n)
∑
i
=
1
n
l
c
m
(
i
,
n
)
∑d|n∑i=1n[gcd(i,n)==d]i∗nd
∑
d
|
n
∑
i
=
1
n
[
g
c
d
(
i
,
n
)
==
d
]
i
∗
n
d
n∗∑d|n∑i=1nd[gcd(i,nd)==1]∗i
n
∗
∑
d
|
n
∑
i
=
1
n
d
[
g
c
d
(
i
,
n
d
)
==
1
]
∗
i
n∗∑d|n∑i=1d[gcd(i,d)==1]∗i
n
∗
∑
d
|
n
∑
i
=
1
d
[
g
c
d
(
i
,
d
)
==
1
]
∗
i
那么最后这个式子就是求得是1~i中与i互质的数的和
这个和等于
φ(n)∗n/2
φ
(
n
)
∗
n
/
2
证明大概如下:
gcd(i,n)=1
g
c
d
(
i
,
n
)
=
1
必有
gcd(n−i,n)=1
g
c
d
(
n
−
i
,
n
)
=
1
于是可以通过对称的方式推导出 因为i和n-i均成对出现
想试着自己写粗来 推来推去 最后的几步还是没推导出
详细证明:https://blog.csdn.net/clover_hxy/article/details/53152358
#include<cstdio>
#include<cctype>
#include<algorithm>
#define ll long long
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if(T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int N=1e6+10;
ll tmp[N],ans[N];int prime[N],tot,phi[N];
bool not_prime[N];
int main(){
freopen("bzoj2226.in","r",stdin);
int T=read();tmp[1]=1;
for (int i=2;i<=1e6;++i){
if (!not_prime[i]) prime[++tot]=i,phi[i]=i-1;
for (int j=1;prime[j]*i<=1e6;++j){
not_prime[prime[j]*i]=1;
if (i%prime[j]==0){
phi[i*prime[j]]=prime[j]*phi[i];break;
}else phi[i*prime[j]]=phi[i]*phi[prime[j]];
}tmp[i]=(ll)phi[i]*i>>1;
}for (int i=1;i<=1e6;++i) for (int j=i;j<=1e6;j+=i) ans[j]+=tmp[i];
while(T--){static int n;
n=read();printf("%lld\n",ans[n]*n);
}
return 0;
}