您的位置:首页 > 其它

51NOD 1040 最大公约数之和(欧拉函数 + 转化)

2017-08-21 21:52 211 查看
给出一个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


对于这道题 1 ~ n 与 n 的最大公约数必定为 n 的因子。这里我们可以O(n^0.5)的复杂度枚举小于sqrt(n)的因子 ai,大于sqrt(n)的因子可以用n / ai 得到。每个因子出现的次数乘以该因子的数值,然后都加起来就是解了。这里不得不说求因子出现个数的转化很巧妙,求 ai 出现的次数等价于求满足 gcd(n,p)= ai 的 p 的个数(p < n),可以转化为求
gcd(n / ai,p / ai)= 1 的 p / ai 的个数即 phi(n / ai)(欧拉函数值),可以在O(n^0.5 logn)解决问题。

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<cmath>

#define ll long long

ll phi(int x)

{

    ll ans = x;

    for(int i = 2;i * i <= x; ++i)

    {

        if(x % i == 0)

        {

            ans -= ans / i;

            while(x % i == 0) x /= i;

        }

    }

    if(x > 1) ans -= ans / x;

    return ans;

}

int main()

{

    int n;

    scanf("%d",&n);

    int maxn = sqrt(n + 0.5);

    ll ans = n;

    for(int i = 2;i <= maxn; ++i)

    {

        if(n % i == 0)

        {

            ans += phi(n / i) * i;

            if(i != n / i) ans += phi(i) * (n / i);

        }

    }

    ans += phi(n);

    printf("%lld\n",n == 1 ? 1 : ans);

    return 0;

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