sss

<更新提示>

<第一次更新>


<正文>

欧拉函数

定义

(forall a,bin N),若(gcd(a,b)=1),则称(a)(b)互质。

对于一个正整数(n),我们将(1-n)中与(n)互质的数的个数称为欧拉函数,记为(phi(n))

求解

若在算数基本定理中,有(n=p_1^{a_1}*p_2^{a_2}*...*p_k^{a_k}),则可以得到:

[phi(n)=n*prod_{i=1}^{k}frac{p_i-1}{p_i} ]

证明:
(p)(n)的一个质因子,则(1-n)(p)的倍数有(p,2p,3p,...,frac{n}{p}p),即(1-n)中不含有因子(p)的数的个数为(n-frac{n}{p})个。
(q)(n)的另一个质因子,由容斥原理可得(1-n)中不含有因子(p)(q)的数的个数为(n -frac{n}{p}- frac{n}{q}+ frac{n}{pq}=n(frac{p-1}{p})(frac{q-1}{q}))个。
推广到(n)的每一个质因子,可得(1-n)中不与(n)含有任何共同质因子的数的个数为(n*prod_{i=1}^{k}frac{p_i-1}{p_i})个,即(phi(n)=n*prod_{i=1}^{k}frac{p_i-1}{p_i})

利用如上公式,我们可以直接在分解质因数的过程中求得一个数的欧拉函数,时间复杂度为(O(sqrt n))

(Code:)

inline long long phi(long long x)
{
    long long ans=x;
    for (long long i=2;i*i<=x;i++)
    {
        if (x%i==0)
        {
            ans=ans/i*(i-1);
            while (x%i==0)x/=i;
        }
    }
    if (x>1)ans=ans/x*(x-1);
    return ans;
}

性质

(1.)对于质数(p),有(phi(p)=p-1)

证明:由定义可得。

(2.)(forall n>1)(1-n)中与(n)互质的数的和为(frac{n}{2}phi (n))

证明:
由于(gcd(n,x)=gcd(n,n-x)),所以与(n)不互质的数(n-x,x)成对出现,且平均值为(frac{n}{2}),因此与(n)互质的数的平均值也为(frac{n}{2})(n)互质的数的和即为(frac{n}{2}phi (n))

(3.)(gcd(a,b)=1),则(phi(ab)=phi(a)phi(b))
(4.)欧拉函数是积性函数,即(n=prod p_i^{a_i})(phi(n)=prod phi(p_i^{a_i}))
(5.)对于一个质数(p),若有(p|n,p^2|n),则(phi(n)=phi(frac{n}{p})*p)
(6.)对于一个质数(p),若有(p|n,p^2 ot | n),则(phi(n)=phi(frac{n}{p})*(p-1))

证明:
可以由欧拉函数的计算式直接推导得到。

(7.)(sum_{d|n}phi(d)=n)

证明:
设函数(f(x)=sum_{d|n}phi(d)),则(f(nm)=sum_{d|nm}phi(d)),若(n,m)互质,利用欧拉函数是积性函数可以得到:$$f(nm)=sum_{d|nm}phi(d)=sum_{d_1|n}sum_{d_2|m}phi(d_1d_2)=sum_{d|n}phi(d)*sum_{d|m}phi(d)=f(n)f(m)$$
即函数(f)为积性函数。

对于一个质数(p),$$f(p^m)=sum_{d|p^m}phi(d)=sum^{m}{i=0}phi(p^i)$$,由等差数列求和可得(f(p^m)=p^m),即可得到$$f(n)=prod{i=1}^{m}f(p_i^{a_i})=prod_{i=1}^{m}p_i^{a_i}=n$$

这些性质在不同的题目中有不同的作用,需要我们注意灵活运用。特别是性质(6.),在(dirichlet)卷积,(Möbius)反演中等内容中也会起到作用。

线性筛求解

对于求解(1-n)所有数的欧拉函数,如果直接使用分解质因数法,时间复杂度为(O(nsqrt n))

事实上,我们可以利用欧拉函数的性质(1. 5. 6.),再线性筛的求解过程中顺带地求解欧拉函数(线性筛见『素数 Prime判定和线性欧拉筛法 The sieve of Euler』)。

(Code:)

inline void eular(void)
{
    for (int i=2;i<=n;i++)
    {
        if (!flag[i])Prime[++cnt]=i,phi[i]=i-1;
        for (int j=1;j<=cnt&&i*Prime[j]<=n;j++)
        {
            flag[ i*Prime[j] ] = true;
            if (i%Prime[j]==0)
            {
                phi[ i*Prime[j] ] = phi[i] * Prime[j];
                break;
            }
            else phi[ i*Prime[j] ] = phi[i] * (Prime[j]-1);
        }
    }
}

<后记>
感谢(hzk) 欧拉函数的介绍(附加欧拉定理和费马小定理的介绍)

原文地址:https://www.cnblogs.com/Parsnip/p/10685470.html