「欧拉函数」学习笔记

欧拉函数$\varphi(n)$表示整数$1到n$中与$n$互质的数的个数。

 

特殊情况

1. $\varphi(1) = 1$

2. 当$n$为素数时,$\varphi(n) = n-1$.

3. 若$n$是素数$p$的$k$次幂,$\varphi(n) = \varphi(p^k) = p^k - p^{k-1} = (p-1)p^{k-1}$

(除掉$p$的倍数即可,由于$p^k = p^{k-1} * p$,故共有$p^{k-1}$个$p$的倍数)

性质1. 当$m, n$互质时,$\varphi(mn) = \varphi(m)\varphi(n)$

这就是欧拉函数的积性性质。欧拉函数是积性函数

设有质数$ p_1, p_2 $,则$ \varphi(p_1^{k_1} * p_2^{k_2}) $按照刚才的方法,总数减去$p_1$的倍数与$p_2$的倍数,再加上重复减掉的$p_1, p_2$的公倍数。

$p_1$的倍数有$ 1 * p_1, 2 * p_1, ... , p_1^{k_1 - 1} * p_2^{k_2} * p_1 $,总共有$p_1^{k_1 - 1} * p_2^{k_2}$个。

同理$p_2$的倍数有$p_1^{k_1} * p_2^{k_2-1}$个。

由于$p_1, p_2互质$,$lcm(p_1, p_2) = p_1 * p_2$,$p_1 * p_2$的倍数有$ 1 * p_1 * p_2, 2 * p_1 * p_2 , ... , p_1^{k_1-1} * p_2^{k_2-1} * p_1 * p_2$,总共有$p_1^{k_1-1} * p_2^{k_2-1}$个

因此我们得到$ \varphi(p_1^{k_1} * p_2^{k_2}) = p_1^{k_1} * p_2^{k_2} -  (p_1^{k_1 - 1} * p_2^{k_2}) - (p_1^{k_1} * p_2^{k_2-1}) + p_1^{k_1-1} * p_2^{k_2-1}$

然后再按照刚才的思路,分开考虑:

$\varphi(p_1^{k_1}) = p_1^{k_1} - p_1^{k_1-1}$

$\varphi(p_2^{k_2}) = p_2^{k_2} - p_2^{k_2-1}$

故$\varphi(p_1^{k_1}) * \varphi(p_2^{k_2}) = p_1^{k_1} * p_2^{k_2} -  (p_1^{k_1 - 1} * p_2^{k_2}) - (p_1^{k_1} * p_2^{k_2-1}) + p_1^{k_1-1} * p_2^{k_2-1}$

这两个式子是一模一样的,所以$\varphi(p_1^{k_1} * p_2^{k_2}) = \varphi(p_1^{k_1}) * \varphi(p_2^{k_2})$

所以$\varphi(mn) = \varphi(n) * \varphi(m)$

 

性质2. 欧拉函数的通式 $\varphi(n) = n * \prod\limits_{i=1}^r \frac{p_i-1}{p_i}$

证明:刚才我们得到了$\varphi(p^k) = (p-1)p^{k-1}$,又得到了欧拉函数的积性性质$\varphi(mn) = \varphi(n) * \varphi(m)$,也可以以此类推三个,四个……

   因此对于任意一个$\varphi(n)$,我们可以对$n$进行质因数分解:

      $n = p_1^{k_1}p_2^{k_2}...p_r^{k_r}$

   对于这个$n$,我们依然使用这个方法,得到$\varphi(n) = \varphi(p_1^{k_1})\varphi(p_2^{k_2})...\varphi(p_r^{k_r})$

   因此就得到了$\varphi(n) = (p_1^{k_1}-p_1^{k_1-1}) * (p_2^{k_2}-p_2^{k_2-1}) ... (p_r^{k_r}-p_r^{k_r-1})$

    $\varphi(n) = \prod\limits_{i=1}^r p_i^{k_i-1}(p_i-1)$

         $  = \prod\limits_{i=1}^r p_i^{k_i} * p_i^{-1}(p_i-1)$

          $ = n * \prod\limits_{i=1}^r \frac{p_i-1}{p_i}$

   因此我们得到通式$\varphi(n) = n * \prod\limits_{i=1}^r \frac{p_i-1}{p_i}$

  有了通式,我们就可以求欧拉函数$\varphi(n)$了:

int a,b,n,phi[N];
main(){
    n = r;
    if(n == 2){ printf("1"); return 0; }
    for(int i = 1; i <= n; ++i) phi[i] = i;
    for(int i = 2; i <= n; ++i){
        if(phi[i] != i) continue;
        for(int j = i; j <= n; j += i) phi[j] = phi[j]/i*(i-1);
    }
    printf("%lld", phi[n]);
    return 0;
}

    以上代码复杂度是$O(n)$的,顺便充当筛素数了。如果$ phi[i]=i $则说明是素数。然后对$n$之内所有以$i$为因子的数都记性上述公式描绘的操作。注意到我们先做了$/i$,然后再做乘。这样是为了避免数据过大而造成数据丢失。

性质3. $\varphi(p * x) = \varphi(x) * p\    (p | x)$ (x, p为整数)

证明:由通式可得 $\varphi(p * x) = p * x * \prod\limits_{i=1}^r \frac{a_i-1}{a_i}$ 

   观察通式我们发现,一个数的欧拉函数其实只和其各个素因数的种类有关,并不关心每种素因数有几个。那么只需要证明$ \varphi(x) =  x * \prod\limits_{i=1}^r \frac{a_i-1}{a_i}$,也就是 $a_1 ~ a_r$包含了$x$与$x*p$的所有种类的素因数 就好了。

   那么由于$p | x$,说明$p$是$x$的约数,所以$p$的所有约数必然包括在$x$之内,所以$x$的所有种类的素因数都是$p * x$的所有种类的素因数是必然的。

   所以我们可以继续推:

   $ \varphi(p * x) =  x * p * \prod\limits_{i=1}^r \frac{a_i-1}{a_i}$

   $ \varphi(p * x) =  \varphi(x) * p$

 

总结一下,当$p$为质数时:若$p|x$,可以利用性质5推得$\varphi(p * x)$。否则$x \% p ≠ 0$,又因为$p$是质数,所以$x, p$一定互质,所以用性质6就可以推得$\varphi(p * x)$。因此当$p$为质数时,无论如何都可以推得$\varphi(p * x)$,因此我们可以利用在线性筛素数的基础上线性完成欧拉函数的求解。

 

/*
 * phi[i]用来表示欧拉函数
 * isprime[i]用来记录i是否是质数 
 * p数组用来存质数 
 */
int n,tot;
int phi[N],isprime[N],p[N]; 
int main(){
    n = r;
    phi[1] = 1;
    for(int i = 2; i <= n; ++i){
        if(!isprime[i]){
            p[++tot] = i;
            phi[i] = i-1;    //若i是质数,则根据特殊情况2, \varphi(i) =  i-1
        }
        for(int j = 1; j <= tot; ++j){
            if(i * p[j] > n) break;  //越界 
            isprime[i * p[j]] = 1;   //存在因子i和p[j],故一定不是质数 
            if(i % p[j] == 0){
                phi[i * p[j]] = phi[i] * p[j]; /*性质5*/
                break;
                /*p[j]是i的素因子之一。由于i % p[j] == 0,所以p[j]也是i的素因子之一。
                 *因为p数组是递增的,因此p[j+1] > p[j],而i内包括了p[j]。p[j]已经作为i * p[j]的素因子了,
                 *所以p[j+1]就一定不是它的最小素因子了。 
                 */
            } 
            else phi[i * p[j]] = phi[i] * (p[j] - 1);
                /*利用性质6,p[j]是质数*/
        }
    }
    printf("%d",phi[n]);
    return 0;
}

 

posted @ 2018-07-15 16:36  DennyQi  阅读(446)  评论(0编辑  收藏  举报