欧拉函数[已解决]

起因:[UVA 10820]Send a Table

疑问:关于欧拉函数的(nloglogn)算法。在代码中的部分,不明白为什么这样就可以求出欧拉函数的值

    phi[1] = 1;
    for (int i = 2; i <= 50001; ++i) if (!phi[i])
    {
        for (int j = i; j <= 50001; j += i)//这一块地方
        {
            if (!phi[j]) phi[j] = j;
            phi[j] = phi[j] / i * (i - 1);
        }
    }

更新:2015.08.24

首先是关于phi数组的定义:小于i且与i互为素数的整数的个数

i 的唯一分解式 : i = p1^a1*p2^a2*p3^a3......(p1 ... pn均为素数)

然后是普通求法是根据容斥原理:phi[i] = i - i / p1 - i / p2 - ...... + i / p1p2 + i / p1p3 + ......

最终简化成:phi[i] = i*( 1 - 1/p1)*(1 - 1/p2)*.......

展开式的每一项,相当于每一次选择1或者-1/pi进行运算,即又变成了未简化前的式子

//注意到简化式中,phi = i*( 1 - 1/p1)*(1 - 1/p2)*......
//在内层循环里枚举素数的倍数,素数倍数的简化式和本身的简化式
//区别在于两处:第一、i的不同;第二、如果本身乘的倍数是素数,
//那么这个倍数就会添加到phi的公式中,即多出来一个(1 - 1/p)
//嘛,这就是原理~
    phi[1] = 1;
    for (int i = 2; i <= 50001; ++i) if (!phi[i])
    {
        for (int j = i; j <= 50001; j += i)
        {
            if (!phi[j]) phi[j] = j;
            phi[j] = phi[j] / i * (i - 1);
        }
    }



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值