欧拉函数浅析

欧拉函数的作用是,计算1~n 内与n互质的个数

  1. 那么我们可以把n拆成质因子相乘
    为什么要拆成质因子相乘呢?
    首先互质等价于没有公约数。
    那么我们把1~n内与n有公约数的数踢掉,剩下的就是互质。

  2. 那么问题来了,怎么判断有公约数了?
    显然把n拆成质因子相乘那么假如与n有公约数的数,显然是要包含这些质因子,所以我们把1~n包含这些质因子的数全踢掉。

  3. 那么该怎么知道了哪些数,包含这些质因子呢?
    显然包含这些质因子的数,肯定是质因子的倍数,所以我们只要把是质因子的倍数的数踢掉,就等价于把,与n有公约数的数踢掉,等价于把与n非互质的数踢掉,剩下的就是互质的数。

  4. 那么问题来了,那怎么统计互质的数呢?

例如60
可以拆成 2,2,3,5
那质因子就是 2,3,5 这三个数

那60里面有多少个是2的倍数了的数了
显然有60*(1/2) = 30个
踢掉30个后,还剩下(1/2)*60个

那么剩下的30个数里面,有多少个是3的倍数了
30*(1/3) = 10个 是3的倍数,踢掉后剩30*(2/3) = 20个

那么多少个是5的倍数了
(1/5)*20 踢掉后剩(4/5)*20
那么显然是(1/2 * 2/3 * 4/5) * 60 只剩下这么多是互质的

下面来看看欧拉函数怎么写

int euler_phi(int n) {
    int m = (int)sqrt(n + 0.5); //计算上界
    int ans = n;
    for(int i = 2; i <= m; i++) {
        if(n % i == 0) { //如果当前这个数是n的质因子
            ans = ans / i * (i-1);
            while(n % i == 0) n /= i; //除去n的质因子
        }
    }
    if(n > 1) ans = ans / n * (n-1); //还剩下最后一个质因子
    return ans;
}

计算1~n中所有的数的欧拉phi函数值。并不要依次计算。可以用和筛选求素数非常类似的方法。

void phi_table(int n) {
    for(int i = 2; i <= n; i++) { //初始化
        phi[i] = 0;
    }
    phi[1] = 1;
    for(int i = 2; i <= n; i++)
        if(!phi[i]) //如果phi[i] == 0则表明i是素数
            for(int j = i; j <= n; j += i) { //将所以i的倍数赋值
                if(!phi[j]) phi[j] = j; //如果j没访问过则phi[j] = j
                phi[j] = phi[j] / i * (i-1); //j的phi值 = j * (质因子i - 1) / (质因子)
            }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值