1040 最大公约数之和

a[] = {1,2,3,4...n}

n与a[i]的最大公约数,必定属于n的因子,所以遍历n的因子。

对于n的一个因子k,我们求出k作为最大公约数出现的次数m

如何求出m呢:

  gcd(n,a[i])==k   =>   gcd(n/k,a[i]/k)==1

这相当与求:小于n/k,且与n/k互质的数的个数,可以用欧拉函数解决

 

#include<stdio.h>
#include<queue>
#include<string.h>
#include<iostream>
#include<algorithm>
#define MAXSIZE 1000005
#define LL long long
using namespace std;

LL Solve(LL n)
{
    LL ans = 1;
    for(int 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 n,ans=0;
    scanf("%lld",&n);
    for(LL i=1;i*i<=n;i++)
    {
        if(n%i!=0)
            continue;
        ans += i*Solve(n/i);
        if(i != n/i)
        {
            ans += (n/i)*Solve(n/(n/i));
        }
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2018-02-03 16:34  声声醉如兰  阅读(276)  评论(0)    收藏  举报