[NOIP2017考前複習] Euler函數與Mobius函數

前排提醒:如無特殊說明,本文中所有符號與《初等數論》(第三版,潘承洞 潘承彪著),北京大學出版社一書中意義相同

關於Euler 函數φ(x)

Euler 函數φ(x) 的定義與基本性質

本着定義是重中之重的原則,我們先來回顧一下Euler 函數的定義:

對於任意正整數n ,我們記小於n 且與n 互素的正整數的個數φ(m)m 的Euler函數。即:

φ(m)=dm[(m,d)=1]

由定義立即可推出它的一些簡單的性質:

  1. φ(m)=m 的既約剩餘系的個數。特別地,對於素數p,φ(p)=p1
  2. m=m1m2 ,若m1m2 的素因子集合相同,那麼φ(m)=m2φ(m1)
  3. m=m1m2 ,若(m1,m2)=1, 那麼φ(m)=φ(m1)φ(m2),Euler 函數φ(x) 是積性函數
  4. m 的標準分解爲m=pαii, 則有φ(m)=m(11pi)
  5. 對於任意正整數m ,都有
    m=d|mφ(d)

這些性質都比較顯然,在這裏不作證明


φ(x) 的計算方法

如果只是詢問一個數的函數值,最顯然的思路就是O(n )求解。

inline int phi(int x)
{
    int ans=x;
    for(int i=2;i<=sqrt(x);i++)  if(x%i==0)
    {
        ans-=ans/i;
        while(x%i==0)  x/=i;
    }
    return ans;
}

但更多的時候我們是需要求很多很多的φ(x) 的值,這樣的做法就顯得不是很妙。
我們發現可以在篩素數的時候順手處理φ(x) 的值,於是就有了下面這兩種很常用的預處理φ(x) 的方法

//Eratosthenes篩法,時間複雜度O(n log log n)
void init()
{
    for(int i=1;i<=maxn;i++)  phi[i]=i;
    for(int i=2;i<=maxn;i++)  if(!vis[i])
    {
        prime[++cnt]=i;  phi[i]--;
        for(int j=i*2;j<=maxn;j+=i)  vis[j]=1,phi[j]-=phi[j]/i;
    }
}
//線性篩法,時間複雜度O(n)
void init()
{
    for(i=2;i<=maxn;i++)
    {
        if(!vis[i])  prime[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j])  phi[i*prime[j]]=phi[i]*(prime[j]-1);
            else
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
        }
    }
}


關於Mobius 函數μ(x)

Mobius 函數μ(x) 的定義與性質

廢話不多說,直接上定義:

對於正整數n>1 ,記其標準分解爲

n=i=1rpαii
則有
μ(x)={(1)r0α1=α2==αr=1else

特別地,有μ(1)=1

從以上定義,可以推出以下幾點性質:

  1. μ(x)0 ,則x 沒有比1 大的平方數因子
  2. (m1,m2)=1 ,則有μ(m1m2)=μ(m1)μ(m2) ,即Mobius 函數μ(x) 是積性函數
  3. 對於任意正整數n ,都有
    d|nμ(d)={10n=1n1
  4. 對於任意正整數n ,都有
    μ(m)=xmodme2πixm
    這裏xmodm 表示對m 的任意一組既約剩餘系求和

前兩個性質比較顯然,下面對性質3與性質4做出簡略的證明

性質3:

n=1 時,命題顯然成立。
n>1 時,記n 的素因子個數爲r ,則由Mobius 函數的定義,有

d|nμ(d)=C0rC1r++(1)rCrr=(11)r=0

性質4:

由複數相關知識,對於任意正整數c ,顯然有

i=1me2πicxm={m0m|celse

m 的標準分解爲
m=i=1rpαii
mj=pαjj(1jr) 以及mjMj=m ,由數論的相關定理,當x(j) 分別遍歷模mj 的縮系時,
x=i=1rMix(i)
遍歷模m 的縮系,於是有
S(m)=xmodme2πixm=x(1)modm1x(r)modmre2πi(M1x(1)+M2x(2)++Mrx(r))m=S(m1)S(m2)S(mr)

容易看出
S(pαjj)=x=1pαjjexp2πixpαjjx=1pαj1jexp2πixpαj1j={10αj=1αj>1
於是性質4得證。


μ(x) 的計算方法

Euler 函數一樣,如果需要單點求值,只需要O(n) 分解素因子即可。

inline int miu(int x)
{
    int ans=1;
    for(int i=1;i<=sqrt(x);i++)  if(x%i==0)
    {
        ans=-ans,x/=i;
        if(x%i==0)  return 0;
    }
    return x>1?-ans:ans;
}

至於多點求值,考慮到μ(x) 是積性函數,我們可以用線性篩來做到O(n) 預處理。

void init()
{
    miu[1]=1;
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i])  prime[++cnt]=i,miu[i]=-1;
        for(int j=1;j<=cnt&&i*prime[j]<maxn;j++)
        {
            int t=i*prime[j];  vis[t]=1;
            if(i%prime[j]==0)  {miu[t]=0;  break;}
            miu[t]=-miu[i];
        }
    }
}

好啦,基礎知識先介紹這麼多,可以開始做題了。


典型習題

BZOJ2705 歐拉函數

題意:
給定正整數N(N232) ,求值

i=1Ngcd(i,N)

分析:
gcd(i,N) 按值分類,問題轉化爲求滿足(i,N)=di 的個數。
由於(i,N)=d 等價於(id,Nd)=1 ,於是所求的個數就是φ(Nd) ,問題的答案即爲
d|Ndφ(Nd)

時間複雜度:O(τ(N)N)
下面貼出代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

int N,m;
LL ans;

inline LL read()
{
    LL ans=0;  char ch=getchar();
    while(ch<'0'||ch>'9')  ch=getchar();
    while(ch>='0'&&ch<='9')  ans=ans*10+ch-'0',ch=getchar();
    return ans;
}
inline LL phi(LL u)
{
    LL ans=u;
    for(int i=2;i<=sqrt(u);i++)  if(u%i==0)
    {
        ans-=ans/i;
        while(u%i==0)  u/=i;
    }
    if(u>1)  ans-=ans/u;
    return ans;
}

int main()
{
    N=read(),m=sqrt(N);
    for(int i=1;i<=m;i++)  if(N%i==0)
    {
        ans+=i*phi(N/i);
        if(N/i!=i)  ans+=N/i*phi(i);
    }
    printf("%lld",ans);
    return 0;
}



BZOJ2818 Gcd

題意:
給定N ,求{1,2,,N}2 中有多少對(x,y) 滿足(x,y) 爲素數
分析:
還是上一題的套路,(i,N)=p 等價於(ip,Np)=1 ,不同的是這一次p 應該取遍所有小於N 的素數。答案爲

2pNϕ([Np])π(N)

其中
ϕ(x)=i=1xφ(i)

時間複雜度:O(n) (線性篩)或O(nloglogn) (埃氏篩)


BZOJ2005 能量採集

這裏用到數論中的一個結論:長爲n 寬爲m 的矩形對角線上(含端點)的整點數爲(n,m)+1
由此可知所求答案即爲

i=1mj=1n(2(i,j)1)
乍一看貌似和上面所說的並沒有太大關係,但我們可以作進一步的代數變形。
我們不妨假設總有mn
i=1mj=1n(2(i,j)1)=2i=1mj=1n(i,j)mn=2i=1mj=1nd|(i,j)φ(d)mn=2i=1mj=1nd=1m[d|i][d|j]φ(d)mn=2d=1mφ(d)j=1n[d|j](i=1m[d|i])mn=2d=1mφ(d)[nd][md]mn

好了,做完了。
時間複雜度同上一題。


SPOJ-VLATTICE

說白了就是求在集合[0,1,2,,N]3 中有多少個三元組滿足(i,j,k)=1
因爲含有數字0,所以分類討論。
座標軸上一共有三個點可視(0,0,1),(0,1,0),(1,0,0) ,而在座標平面內,點的個數是2ϕ(N)1 ,其中ϕ(x) 的含義同上上題。因此,只需要求

i=1Nj=1Nk=1N[(i,j,k)=1]

Mobius 函數的性質3得
i=1Nj=1Nk=1N[(i,j,k)=1]=i=1Nj=1Nk=1Nd=1N[d|i][d|j][d|k]μ(d)=d=1Nμ(d)[Nd]3

綜上,最終答案爲
Ans(N)=6ϕ(N)+d=1Nμ(d)[Nd]3
對於每個詢問O(N) 計算即可。總複雜度O(TN)


未完待續。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章