poj 2407Relatives(数论:欧拉函数)

典型的欧拉函数应用,关于欧拉函数介绍如下:

欧拉函数φ(n)是用来求少于或等于n的数中与n互质的数的数目

公式如下:

φ(n)=n*(1-1/p[1])*(1-1/p[2])*...*(1-1/p[k])//p[i]用来指n的第i个素因子
有公式就很好求解了,现在的问题就是怎么找到小于等于n且与n互质的因子呢

很容易处理,我们从2开始遍历到sqrt(n+0.5)

期间遇到n的因子x,令n把因子x除尽(n/x知道x与n互质)即可保证之后遇到的因子均为n的质因子

这样做的原因是什么呢?

很简单,因为n的某个非质因子必然由更小的质因子相乘得到,因此在遇到这个非质因子之前,除尽更小的质因子,即可保证该非质因子不会出现

代码实现如下:

#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 10010
#define LL long long
using namespace std;

LL euler_phi(LL n) {
    LL m = (LL)sqrt(n+0.5);
    LL ans = n;
    for(int i=2; i<=m; ++i) {
        if(n % i == 0) {
            ans = ans/i*(i-1);这里先乘后除会快很多
            while(n%i == 0)
                n /= i;
        }
    }
    if(n > 1)//这里处理的原因见代码下面解释
        ans = ans/n*(n-1);
    return ans;
}

int main(void) {
    LL n;
    while(cin >> n, n) {
        cout << euler_phi(n) << endl;
    }
    return 0;
}

为什么还要对n单独处理呢?

原因很简单:

对应的是n本身就是一个质数的情况,这时答案恰好为(n-1)


一个很神奇的现象就是我把乘除的顺序换了下,时间就快了很多


具体原因我也不太清楚,应该和计算机的底层实现有关吧,哪位朋友了解的话还希望不吝赐教大笑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值