【思路】:本來是TLE的,但看了討論區,發現要用到歐拉函數(在數論中用於求解 [ 1 , n ] 中與 n 互質數個數 的函數),但歐拉開頭的東東就有挺多的,這裏用到的是單個數的那種歐拉函數的板子,這裏給你一個通式:
求單個數的歐拉函數的板子:
//本題數據較大,所以板子用long long
typedef long long ll;
ll Eular(ll m)
{
ll i;
ll res=m;
for(i=2;i*i<=m;i++)
{
if(m%i==0)
{
res-=res/i;
while(m%i==0)
m/=i;
}
}
if(m>1)
res-=res/m;
return res;
}
給出一個n,求1-n這n個數,同n的最大公約數的和。比如:n = 6
1,2,3,4,5,6 同6的最大公約數分別爲1,2,3,2,1,6,加在一起 = 15
收起
輸入
1個數N(N <= 10^9)
輸出
公約數之和
輸入樣例
6
輸出樣例
15
ac代碼:
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
const ll maxn=1e6+7;
ll Eular(ll m)
{
ll i;
ll res=m;
for(i=2;i*i<=m;i++)
{
if(m%i==0)
{
res-=res/i;
while(m%i==0)
m/=i;
}
}
if(m>1)
res-=res/m;
return res;
}
int main()
{
ll i,n;
cin>>n;
ll ans=0;
for(i=1;i*i<=n;i++)
{
if(n%i==0){
ans+=Eular(n/i)*i;
if(n!=i*i)
ans+=Eular(i)*(n/i);
}
}
cout<<ans<<endl;
return 0;
}