[bzoj2226][SPOJ5971]LCMSUM

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=1ningcd(i,n)

ni=1nigcd(i,n)

nd|ni=1nid(gcd(i,n)==d)

nd|nj=1ndj(gcd(i,nd)==1)(j=id)

nd|nj=1dj(gcd(i,d)==1)(ndd)

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)=dphi[d]2

ans=d|ndphi[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[N];
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);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值