莫比烏斯反演是數論中非常重要的一部分,它可以將一個本來只能用時間復雜度極高的枚舉求和過程,通過反演變成一個線性時間復雜度甚至根號級別的時間復雜度的問題。在這里,總結一下本人在學習莫比烏斯反演(附帶一部分歐拉反演)時的經驗和技巧。
在說反演之前先說一個大多數反演問題都能用到的部分——整除分塊
什么是整除分塊?舉個例子,求$\sum\limits_{i=1}^{n}i\left \lfloor \frac{n}{i} \right \rfloor$,如果暴力枚舉要O(n)的時間復雜度,但可以發現對於不同的i,有許多$\left \lfloor \frac{n}{i} \right \rfloor$ 是相等的,而$\left \lfloor \frac{n}{i} \right \rfloor$只有√n種取值。因此可以把取值相同的i分成同一塊,求每一塊值時只要將這一段的i之和用前綴和處理出來乘上對應的$\left \lfloor \frac{n}{i} \right \rfloor$就好了,時間復雜度降到了根號級別。
代碼很簡短
int add(int n) { int ans=0; int r; for(int l=1;l<=n;l=r+1) { r=n/(n/l); ans+=(sum[r]-sum[l-1])*(n/l); } }
兩個整除分塊套在一起的也是同樣的
int add(int n,int m) { int ans=0; int r; if(n>m) { swap(n,m); } for(int l=1;l<=n;l=r+1) { r=min(n/(n/l),m/(m/l)); ans+=(sum[r]-sum[l-1])*(n/l)*(m/l); } return ans; }
一、歐拉反演
歐拉反演不怎么實用,但在做某些題時要比莫比烏斯反演要簡便。對於一些求權值和的反演題比較合適。核心公式是$n=\sum\limits_{d|n}^{ }\phi(d)$。
證明:我們把1~n所有數按與n的gcd分類,
$n=\sum\limits_{d|n}^{ }\sum\limits_{i=1}^{n}[gcd(i,n)==d]$
$n=\sum\limits_{d|n}^{ }\sum\limits_{i=1}^{\frac{n}{d}}[gcd(i,\frac{n}{d})==1]$
$n=\sum\limits_{d|n}^{ }\phi(\frac{n}{d})$
因為一個數的約數是"對稱"的,所以
$n=\sum\limits_{d|n}^{ }\phi(d)$
知道了公式怎么反演呢?歐拉反演的原理就是把一些式子里求的值,強行換成$\sum\limits_{d|x}^{ }\phi(d)$形式,其中x就是要求的值。
具體怎么實現呢?舉個例子:
求$\sum\limits_{i=1}^{n}gcd(i,n)$
求的是所有gcd的值,那么我們可以把gcd(i,n)看成是公式里的n,反演后就是
$\sum\limits_{i=1}^{n}\sum\limits_{d|gcd(i,n)}^{ }\phi(d)$
繼續推導能得到
$\sum\limits_{i=1}^{n}\sum\limits_{d|i}^{ }\sum\limits_{d|n}^{ }\phi(d)$
$\sum\limits_{d|n}^{ }\sum\limits_{i=1}^{n}\sum\limits_{d|i}^{ }\phi(d)$
對於每個d,在n的范圍內只對n/d個數有貢獻,因此得到
$\sum\limits_{d|n}^{ }\frac{n}{d}\phi(d)$
這樣只要O(√n)枚舉約數求歐拉函數就好了。
歐拉反演部分就這么多,雖然不適用於所有反演題,但有時如果用莫比烏斯反演不太容易可以試試歐拉反演。
二、莫比烏斯反演
莫比烏斯反演適用於幾乎所有反演題,用於做一些求成立方案數的題,對於求權值和的題可以轉化成求方案數一類的問題再進行反演。莫比烏斯反演的核心公式是
$\sum\limits_{d|n}^{ }\mu(d)=\epsilon(n),\epsilon(n)=1,n=1;\epsilon(n)=0,n\neq1$
證明:
將n質因數分解可得n=p1a1p2a2……pkak,由莫比烏斯函數定義可知,非零取值的μ(d)只有d=p1a1p2a2……pkak,其中ai取值為1或0,也就是所有質因子的組合數,即
$(x+y)^k=\sum\limits_{i=0}^{k}C_{k}^{k-i}x^iy^{k-i}$沒錯,就是二項式定理! 其中x代表選這個質因子,y代表不選。因為選了奇數個值為-1,偶數個值為1,沒選的數對結果沒影響,所以x=-1,y=1,x+y=0,這時要討論n是否為1,如果不為1,那么結果就是0了!
莫比烏斯反演的原理就是把原式中判斷是否等於1的部分換成$\sum\limits_{d|x}^{ }\mu(d)$ 形式,其中x為原式中判斷是否等於1的部分。因為剛才證明了,只有當x=1時才有貢獻,與判斷是否等於1效果相同。
在舉例子之前再介紹一個十分有用的公式
$\phi(n)=\sum\limits_{d|n}^{ }d*\mu(\frac{n}{d})$
怎么來的呢?我們設$f(n)=n,g(n)=1,h(n)=\phi(n)$,
$h(n)*g(n)=\sum\limits_{d|n}^{ }\phi(d)=n=f(n)$其中$*$代表狄利克雷卷積
將等式兩邊同時卷上μ(n)
$h(n)*g(n)*\mu(n)=f(n)*\mu(n)$
因為卷積有結合律和交換律
$h(n)*(g(n)*\mu(n))=f(n)*\mu(n)$
將合並的卷積展開得到
$h(n)*(\sum\limits_{d|n}^{ }\mu(d))=\sum\limits_{d|n}^{ }d\cdot \mu(\frac{n}{d})$
即
$h(n)*\epsilon(n)=\sum\limits_{d|n}^{ }d\cdot \mu(\frac{n}{d})$
再合並得到
$\sum\limits_{d|n}^{ }\epsilon(d)\cdot\phi(\frac{n}{d})=\sum\limits_{d|n}^{ }d\cdot \mu(\frac{n}{d})$
因為當d為1時$\epsilon(d)$才有貢獻,這時n/d為n左邊即為$\phi(n)$,右邊就是上面公式里給出的部分。
下面正式開始莫比烏斯反演!
求$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}gcd(i,j)$
顯然這是一個求權值和的題,但可以轉化成判斷是否成立。
我們設gcd(i,j)=d,優先枚舉d,判斷哪些(i,j)的gcd等於d,為了方便假設n<m
$\sum\limits_{d=1}^{n}d\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)==d]$
因為i與j一定要是d的倍數,所以可以把i,j都除去d,轉換為判斷除去后的i,j是否互質
$\sum\limits_{d=1}^{n}d\sum\limits_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum\limits_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}[gcd(i,j)==1]$
這樣就可以莫比烏斯反演了!按照上面說的反演套路把后面的部分換掉。
$\sum\limits_{d=1}^{n}d\sum\limits_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum\limits_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}\sum\limits_{p|gcd(i,j)}^{ }\mu(p)$
優先枚舉p,即統計每個p對多少對數有貢獻
$\sum\limits_{d=1}^{n}d\sum\limits_{p=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\mu(p)\left \lfloor \frac{n}{dp} \right \rfloor\left \lfloor \frac{m}{dp} \right \rfloor$
當反演時,見到dp就把它換成Q,將前面的枚舉d和p換成枚舉Q統計每個Q的貢獻
$\sum\limits_{Q=1}^{n}\sum\limits_{d|n}^{ }d\cdot\mu(\frac{Q}{d})\left \lfloor \frac{n}{Q} \right \rfloor\left \lfloor \frac{m}{Q} \right \rfloor$
中間那部分是不是很熟悉?沒錯,就是上面講的公式。
$\sum\limits_{Q=1}^{n}\phi(Q)\left \lfloor \frac{n}{Q} \right \rfloor\left \lfloor \frac{m}{Q} \right \rfloor$
直接線篩歐拉函數然后整除分塊就好了!
莫比烏斯反演的過程大致就是這樣的,當然還有些題會篩一個卷積形式的積性函數,用篩積性函數的套路篩就好了。積性函數的線性篩可參見->線性篩法