数论-欧拉函数

欧拉函数

1、定义

欧拉函数\(\varphi(n)\)表示小于或等于\(n\)的整数中于\(n\)互质的数的数目。

2、欧拉函数值

欧拉函数具有积性(俺不会证),若\(n\)\(m\)互素,则:

\[\varphi(m*n)=\varphi(m)*\varphi(n) \]

所以,若\(n=p_1^{k_1}p_2^{k_2}...p_r^{k_r}\),则\(\varphi(n)=\varphi(p_1^{k_1})\varphi(p_2^{k_2})...\varphi(p_r^{k_r})\)
又:

\[\varphi(p^k)=p^k-p^{k-1}=p^{k-1}(p-1) \]

即若n为素数p的k次,那么他的欧拉函数值为n减去1~n中p的倍数的个数。所以

\[\varphi(n)=\sum_i^r(p_i^{k_i-1}(p_i-1))=n\prod_{i=1}^r(\frac{p_i-1}{p_i}) \]

特殊的\(\varphi(1)=1\).

3、性质

(1)积性函数
(2)若\(xmod2=1,\)\(\varphi(2*x)=\varphi(x)\)
(3)\(\sum_{d|n}\varphi(d)=n\)
(4)

\[\varphi(x)=\begin{cases} \varphi(x/p)·p & \text{gcd(x/p,p)=p}\\ \varphi(x/p)·(p-1) & \text{gcd(x/p,p)=1} \end{cases} \]

4、代码实现

基于素因数分解的欧拉函数算法:
时间复杂度\(O(\sqrt n)\)
数据量较大可以考虑先来一发欧拉筛预处理。

ll eulerfunc(ll n){
    ll sum=n;
    for(ll i=2;i*i<=n;++i){
        if(n%i==0) sum=sum/i*(i-1);
        while(n%i==0) n/=i;
    }
    if(n!=1) sum=sum/n*(n-1);
    return sum;
}

欧拉筛线性求欧拉函数:
时间复杂度为\(O(n)\)
该算法利用了性质(4),求n以内的欧拉函数值

void eulerfunc(ll n){
    ph[1]=1;
    cmt=0;
    for(int i=2;i<=n;++i){
        if(!isp[i]) {
            p[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*p[j]<=n;++j){
           isp[i*p[j]]=1;
           if(i%p[j]==0) {
               phi[i*p[j]]=phi[i]*p[j];//gcd(x/p,p)=p
               break; 
           }
           else{
               phi[i*p[j]]=phi[i]*(p[j]-1);//gcd(x/p,p)=1
           }
        } 
    }
}
posted @ 2021-06-04 09:43  七铭的魔法师  阅读(349)  评论(0编辑  收藏  举报