您的位置:首页 > 其它

51nod-1040-最大公约数之和(欧拉函数)

2016-05-06 14:53 393 查看
给出一个n,求1-n这n个数,同n的最大公约数的和。比如:n = 6
1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15

Input
1个数N(N <= 10^9)


Output
公约数之和


Input示例
6


Output示例
15


小推下公式:

sigma(n,i=1)gcd(n,i)

=sigma(d|n)sigma(n,i=1)gcd(n,i)=d

=sigma(d|n)sigma(n/d,i=1)gcd(n/d,i)

枚举n的因子x,求gcd(n,i)=x的个数,即gcd(n/x,i/x)=1的个数,就是求phi(n/x)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug\n"
using namespace std;
const int MAXN = 1e5+7;
const int MAXM = 1e9+7;
long long phi[MAXN];
/*
void get_euler()
{
memset(phi,0,sizeof(phi));
phi[1]=1;
for(long long i=2; i<MAXN; ++i)
if(!phi[i])
for(long long j=i; j<MAXN; j+=i)
{
if(!phi[j])
phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}*/
long long euler(long long n)
{
long long ans=n;
for(long long i=2; i*i<=n; ++i)
if(n%i==0)
{
ans-=ans/i;
while(n%i==0)n/=i;
}
if(n>1)ans-=ans/n;
return ans;
}
int main()
{
long long n;
//get_euler();
while(scanf("%I64d",&n)!=EOF)
{
long long ans=0;
for(long long i=1; i*i<=n; ++i)
{
if(n%i==0)
{
ans+=i*euler(n/i);
if(n!=i*i)ans+=n/i*euler(i);
}
}
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: