【持續更新】莫比烏斯反演簡明教程

前言

開始學省選算法了……

感覺莫比烏斯反演好厲害的樣子,就先學習一下

一入反演深似海……

相關的東西太多了,以後會不定期更新

前置技能

莫比烏斯函數

莫比烏斯函數μ(n) 的定義如下:

n=pk11pk22pkmm

μ(n)=1(1)m0n=1mi=1ki=1otherwise(ki>1)

顯然,μ(n) 是積性函數:μ(x)μ(y)=μ(xy),xy

那麼我們就可以使用線性篩來得到μ(n)

void prepare(){
    mu[1]=1;
    for (int i=2;i<=N;i++){
        if (!vis[i]) p[++p[0]]=i,mu[i]=-1;
        for (int j=1;j<=p[0]&&i*p[j]<=N;j++){
            vis[i*p[j]]=1;
            if (i%p[j]==0) {mu[i*p[j]]=0;break;}
             else mu[i*p[j]]=-mu[i];
        }
    }
}

狄利克雷卷積

定義:對於數論函數f(n)g(n) ,定義卷積運算 爲:

(fg)(n)=d|nf(d)g(nd)

狄利克雷卷積的單位元爲e(x)=[x=1]

任何數論函數f 滿足fe=f

定義函數I(x)=1id(x)=x

則有:Iμ=e

這說明μI 的逆元

又有:φI=id

那麼可以得到φ=idμ

莫比烏斯反演

對於f(n),g(n) 滿足:

f(n)=d|ng(d)

則有莫比烏斯反演:
g(n)=d|nf(d)μ(nd)

其實非常顯然,把命題換成狄利克雷卷積的形式就是:

已知f=gI ,求證g=fμ

根據Iμ=e 直接證明了

應用

求gcd=k的個數

問題:求

i=1nj=1m[gcd(i,j)=k]

這是莫比烏斯反演的入門題,非常經典

推導:

i=1nj=1m[gcd(i,j)=k]i=1nkj=1mk[gcd(i,j)=1]

然後套用莫比烏斯反演:
i=1nkj=1mkd|(i,j)μ(d)dμ(d)d|id|j1dμ(d)nkdmkd

然後就可以對nkdmkd 分塊求和了

然後就可以在O(n) 時間裏解決每次詢問(O(n) 預處理)

例題

YY的GCD

BZOJ2820

先考慮枚舉質數p,答案就是:

pdμ(d)npdmpd

T=pd ,考慮枚舉T ,則有:
Tmin{n,m}nTmTp|Tμ(Tp)

如果能夠預處理p|Tμ(Tp) 關於T 的前綴和,前面的柿子就可以O(n) 求解

其實可以暴枚p

因爲均攤每個質數是ln(n) 的,而質數的個數是nln(n)

所以預處理可以O(n)

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