[数学基础] 7 欧拉函数

欧拉函数

非常有用的欧拉函数!嗯……好像应该放在四大定理前讲的来着QAQ

1. 欧拉函数的定义

  • 定义φ(N)1~N中与N互质的数,假设N可以表达为p1a1×p2a2...pkaki[1,k],pi为质数,ai>0

    φ(N)=N×(11p1)×(11p2)...(11pk)

特别的,规定φ(1)=1。(唯一和1互质的数就是1本身)

证明:容斥原理

  1. 先去掉1~N中p1的倍数,再去掉1~N中p2的倍数,……直到去掉1~N中pk的倍数。那么,此时答案就是

    NNp1Np2...Npk

  2. 这个答案,将pi×pj,(i,j[1,k],ij)重复减去了多次,需要把它们加回来

    NNp1Np2...Npk+Np1p2+Np1p3+...+Npk1pk

  3. 考虑这样的三元组papbpc,它们先是被1中的式子pa,pb,pc减去了三次,又在2中的式子papb,papc,pbpc中加了三次,总体没加也没减。因此要把三元组的倍数从N中减去

    NNp1Np2...Npk+Np1p2+Np1p3+...+Npk1pkNp1p2p3...Npk2pk1pk

  4. 以此类推,最终化简上面的式子,可得

    N×(11p1...1pk+1p1p2+...+1pk1pk...)=N×(11p1)×(11p2)...(11pk)

  • 时间复杂度:欧拉函数时间复杂度最大的地方在于分解质因数,因此时间复杂度为O(N)

欧拉函数模板

int phi(int x){
    int res = x;
    for (int i=2;(ll)i*i<=x;++i){
        if (x % i == 0){
            res = res / i * (i - 1);
            while (x % i == 0) x /= i;
        }
    }
    if (x > 1) res = res / x * (x - 1);
    return res;
}

2. 欧拉函数的性质

性质1
  • a=n×φ(n)2,n>1,a[1,n),(a,n)=1
性质2
  • n>2,φ(n)为偶数。

证明:(n,x)=(n,nx),n>x

假设x[1,n)(n,x)=(n,nx)=1,x=nx,n>2,则n=2x,矛盾。

[1,n)中与n互质的数均是成对出现的,因此[1,n)n互质的数是偶数,即φ(n)为偶数。

观察(n,x)=(n,nx)=1,也说明了任意一对与n互质的数,相加均为n,所以有a=n×φ(n)2

性质3
  • d|nφ(d)=n

f(n)=φI=d|nφ(d),则f(n)为一个积性函数。

n唯一分解为n=i=1kpiai=p1a1p2a2..pkak,则

f(piai)=φ(1)+φ(pi)+..+φ(piak)=1+(p1)+..+(pkpk1)=pk

f(n)=f(p1a1)×f(p2a2)×..×f(pkak)=i=1kpiai=n,证毕。

性质4
  • 欧拉函数为积性函数,但不是完全积性函数,当(n,m)=1时,满足φ(m×n)=φ(m)×φ(n)。那么显然,当n唯一分解后,φ(n)=i=1kφ(piai)

证明:若(n,m)=1,则n,m没有相同的质因子,记n的质因子个数为c1m的质因子个数为c2,则

φ(n)×φ(m)=n×m×i=1c1(11pi)×i=1c2(11pi)=i=1c1+c2(11pi)=φ(n×m)

例题:cf776E The Holmes Children

性质5
  • φ(n)n=dnμ(d)d

写成狄利克雷卷积的形式

φI=idφIμ=idμ

φ(Iμ)=idμ

φe=idμ

φ(n)=d|nnd×μ(d),也就是φ(n)n=dnμ(d)d

性质6

n=pk时,φ(n)=pkpk1

证明:当n只有一个质因数时,φ(n)=pk×(11p)=pkpk1

3. 筛法求欧拉函数

假设目前已知φ(i)的值,pj为某一质数,求φ(i×pj)的值。

i表示为p1a1×p2a2...pkakφ(i)=i×(11p1)×(11p2)...(11pk)

  1. i%pj==0时,i×pj中不存在新的质因子

    φ(i×pj)=i×pj×(11p1)×(11p2)...(11pk)=φ(i)×pj

  2. i%pj0时,pj为新的质因子

    (1)φ(i×pj)=i×pj×(11p1)×(11p2)...(11pk)×(11pj)(2)=φ(i)×pj×(11pj)(3)=φ(i)×(pj1)

  • 代码
int n, cnt;
const int N = 1e6 + 10;
int E[N], p[N];
bool st[N];

void Eulers(){
    E[1] = 1;
    for (int i=2;i<=n;++i){
        if (!st[i]){
            p[++cnt] = i;
            E[i] = i - 1;
        }
        for (int j=1;p[j]<=n/i;++j){
            int t = p[j] * i;
            st[t] = true;
            if (i % p[j] == 0){
                E[t] = E[i] * p[j];
                break;
            }
            E[t] = E[i] * (p[j] - 1);
        }
    }
}
posted @   跳岩  阅读(259)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示