您的位置:首页 > 其它

[bzoj2226][SPOJ5971]LCMSUM

2015-10-14 23:07 253 查看

2226: [Spoj 5971] LCMSum

Time Limit: 20 Sec Memory Limit: 259 MB

Submit: 949 Solved: 427

[Submit][Status][Discuss]

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

首先我们先化简一下式子:

∑i=1nlcm(i,n)

∑i=1ni∗ngcd(i,n)

n∗∑i=1nigcd(i,n)

n∗∑d|n∑i=1nid(gcd(i,n)==d)

n∗∑d|n∑j=1ndj(gcd(i,nd)==1)(j=id)

n∗∑d|n∑j=1dj(gcd(i,d)==1)(nd和d等价)

令f[i]=∑i=1di(gcd(i,d)==1)

f[i]就表示1~d中与i互质的数的和。怎样去求f[i]呢?

首先如果gcd(x,n)==1,那么gcd(n-x,n)==1

证明:如果gcd(n-x,n)=d(d!=1) 那么n-x=d(n1-x1),那么gcd(x,n)=d>1所以得证。

根据上面的这个性质,我们就可以将与d互质的数分为x和d-x两部分。因因为x+d-x=d,所以

f[i]=∑i=1di(gcd(i,d)==1)=d∗phi[d]2

ans=∑d|nd∗phi[d]2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=1000010;
#define LL long long
int n,T,phi
;
inline void prepare(){
int i,j;
phi[1]=1;
for(i=2;i<=N;++i)
if(!phi[i])
for(j=i;j<=N;j+=i){
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
inline void calc(int x){
int i;
LL ans=0;
for(i=1;i<=sqrt(x);++i)
if(!(x%i)){
if(i!=1) ans+=(LL)i*(LL)phi[i]/2;
else ans+=1;
if(x/i!=i) ans+=(LL)(x/i)*(LL)phi[x/i]/2;
}
printf("%lld\n",ans*(LL)(x));
}
int main(){
prepare();
scanf("%d",&T);
while(T--){
scanf("%d",&n);
calc(n);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: