51nod1040&poj 2480(欧拉函数-最大公约数)1-n同n的最大公约数之和

题目

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

输出

公约数之和

分析

题意很明确,求同n的最大公约数的和。如果n的范围很小,小至10^6,那么这就是一道数学题,但是n的范围很大,所以这就是一个数论题了。先来看一下当n=6时,结果15是咋来的,n=6时,1与6的最大公约数是1;2与6的最大公约数是2;3与6的最大公约数是3;4与6的最大公约数是2;5与6的最大公约数是1;6与6的最大公约数是6;那么用一个num数组来存就是num[6] = {1,2,3,2,1,6};其中1出现2次,2出现了2次,3出现1次,6出现1次。此时我们就惊奇的发现,1、2、3、6都是6的因子。用数组divisor[4] = {1,2,3,6};来表示6的因子。用cnt[4] = {2,2,1,1};来表示因子出现的次数。那么为什么1的时候出现2次、2出现了2次,3出现1次,6出现1次呢?其实这里就用到了数论里边的欧拉函数的知识,如果一个数i与6的最大公约数是1,那么i/1与6/1必然是互质的(因为两个数p和q的最大公约数是k,那么p/k与q/k互质)。那么此时只需求出6/1的欧拉数便是6与i最大公约数是1的数。6/1的欧拉数的项的数分别是1和5两个数,那么6与i的最大公约数是1的数分别是1×1和1×5。所以cnt[0] = 2;同理,例如一个数i与6的最大公约数是2时,i/2与6/2必然是互质的。6/2的欧拉数的项的数分别是1和2两个数。那么6和i的最大公约数是2的数分别是2×1和2×2,既是2和4;同理最大公约数为3的数是3×1、最大公约数为6的数是6×1,所以cnt数组的内容是{2,2,1,2}。

以上是详细过程,下面是简单过程。
先找出n的因子,假设为x,如果一个数i与n的最大公约数是x,那么必定 i/x 与 n/x 互质,既是gcd( i / x , n / x) = 1,看到这个式子可以想到欧拉函数,也就是求比n/x小的与其互质的个数。然后因子*(n/x的欧拉数)求和即可。

代码如下

#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
ll euler(ll x)
{
    ll res = x;
    for(int i = 2; i*i <=x; i++)
    {
        if(x%i==0)
        {
            res = res/i*(i-1);
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        res = res/x*(x-1);
    return res;
}
int main()
{
    ll n, sum = 0;
    scanf("%lld", &n);
    ll k = sqrt(n);
    for(int i = 1; i <= k; i++)
    {
        if(n%i == 0)
        {
            sum += i*euler(n/i);     //因子i*(n/i的欧拉数)
            if(i*i!=n)
                sum += n/i*euler(i);
        }
    }
    printf("%lld", sum);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值