您的位置:首页 > 其它

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

2016-05-31 23:03 197 查看
1040 最大公约数之和
题目来源: rihkddd
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题

给出一个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


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

给你n,然后求[1-n]所有数与n的最大公约数的和
n的最大公约数必定是n的因子v,所以考虑枚举因子分别求他们的个数num,那么因子v对答案的贡献就是v*num
相当于求[1-n]中 GCD(a[i],n) = v的个数,也就成了GCD(a[i]/v,n/v)=1的个数。 欧拉函数求出即可。

欧拉函数:[1-n]中 gcd[i,n]=x的个数

hhh-2016/05/27  11:09:03
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;
const int maxn = 1040;
typedef long long ll;
ll eular(ll n)
{
ll ans=1;
for(ll i=2; i*i<=n; i++)
{
if(n%i==0)
{
n/=i;
ans*=i-1;
while(n%i==0)
{
n/=i;
ans*=i;
}
}
}
if(n>1)
ans*=n-1;
return ans;
}

int main()
{
ll x;
scanf("%I64d",&x);
ll ans = 0;
for(ll i = 1 ; i*i <= x; i++)
{
if(x % i != 0)
continue;
ll t = x/i;
ans += i*eular(t);
//cout << i  << ": " << eular(t) << endl;
if(i != t)
{
ans += (t)*eular(x/t);
//cout << t  << ": " << eular(x/t) << endl;
}
}
printf("%I64d\n",ans);
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: