欧拉函数详解

时间:2022-05-08
本文章向大家介绍欧拉函数详解,主要内容包括欧拉函数、性质、计算方法、线性筛、例题、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

欧拉函数

我们用phi(n)表示欧拉函数

定义:phi(n)表示对于整数n,小于等于n中与n互质的数的个数

性质

1.phi(n)为积性函数

证明:

此处证明需要用到下面计算方法1中的内容,建议先看后面再回过头来看这里

假设存在p,q,且p*q=n

将n,p,q进行质因数分解

n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}

p=a_1^{p_1}*a_2^{p_2}...*a_m^{p_m}

q=a_{m+1}^{p_{m+1}}*a_{m+2}^{m+2}...*a_k^{p_k}

那么

varphi left( nright) =nprod ^{k}_{i=1}left( 1-dfrac {1}{p_{i}}right)

varphi left( aright) =aprod ^{m}_{i=1}left( 1-dfrac {1}{p_{i}}right)

varphi left( bright) =bprod ^{k}_{i=m+1}left( 1-dfrac {1}{p_{i}}right)

因为n=a*b

显然

varphi left( nright) =varphi left( aright) varphi left( bright)

这种方法也是常见的证明一个函数是积性函数的方法

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

3.1到n中与n互质的数的和为n*dfrac{phi(n)}{2}(n>1)

计算方法

sqrt(n)计算单值欧拉函数

假设我们需要计算phi(n)

分情况讨论

1.当n=1时

很明显,答案为1

2.当n为质数时

根据素数的定义,答案为n-1

(仅有n与n不互质)

3.当$n$为合数时

我们已经知道了n为素数的情况

不妨对n进行质因数分解

n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}

假设$k=1$

那么phi(p^k)=p^k-p^{k-1}

证明:

考虑容斥,与一个数互素的数的个数就是这个数减去与它不互素的数的个数

因为p是素数,所以在p^k中与其不互素的数为1*p,2*p....p^{k-1}*p,有p^{k-1}个

得证

kneq 1

phi(n)

=varphi left( a^{p_{1}}_{1}a^{p_{2}ldots }_{2}a^{Pk}_{k}right)

=prod ^{k}_{i=1}a^{P_i}-a^{P_{i}-1}_{i}

=prod ^{k}_{i=1}a^{Pi}_{i}(1-dfrac {1}{p_{i}})

=n*prod ^{k}_{i=1}(1-dfrac {1}{p_{i}})

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define LL long long 
using namespace std;
int main()
{
    LL N;
    while(cin>>N&&N!=0)
    {
        int limit=sqrt(N),ans=N;
        for(int i = 2; i <= limit ; ++i)
        {
            if(N%i==0) ans=ans/i*(i-1);
            while(N%i==0) N=N/i;
        }
        if(N>1) ans=ans/N*(N-1);
        printf("%dn",ans);
    }
    return 0;
}

线性筛

因为欧拉函数是积性函数

因此可以使用线性筛法

性质1

若p为素数,则varphi left( pright) =p-1

证明:

在1-p中,只有(p,p)neq1

性质2

i mod p neq  0,且p为素数

varphi left( i*pright) =varphi left( iright) *varphi left( pright)

=varphi left( iast pright) =varphi left( iright) ast left( p-1right)

这一步同时利用了性质1和欧拉函数的积性

性质3

i mod p = 0,且p为素数,

varphi left( iast pright) =varphi left( iright) ast p

证明:

没怎么看懂,丢一个链接

http://blog.csdn.net/Lytning/article/details/24432651

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define LL long long 
using namespace std;
const int MAXN=1e6+10;
int prime[MAXN],tot=0,vis[MAXN],phi[MAXN],N=10000;
void GetPhi()
{
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])
        {
            prime[++tot]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=tot&&prime[j]*i<=N;j++)
        {
            vis[ i*prime[j] ] = 1; 
            if(i%prime[j]==0)
            {
                phi[ i*prime[j] ]=phi[i]*prime[j];
                break;
            }
            else phi[ i*prime[j] ]=phi[i]*(prime[j]-1);
        }
    }
}
int main()
{
    GetPhi();
    cin>>N;
    printf("%dn",phi[N]);
    return 0;
}

例题

放几道水题

http://poj.org/problem?id=2407

题解

http://poj.org/problem?id=2478

题解

https://www.luogu.org/problemnew/show/P2158

题解