前言 (chě dàn)
反演好神奇啊
就像 膜 魔法一樣
反演在OI界還是一個非常常用的一個東西,覺得還是寫個總結好一點
前置知識
二項式定理 : (證明可通過數學歸納法)
正文
定義
何爲反演 ?
我是通俗理解爲已知 A 求 B爲正演, 那已知 B 求 A爲反演
在OI中一般 A, B爲函數,如f(x), g(x)之類的
引入
先通過一個例題引入
有 n 個人站成一排, 編號爲1, 2, 3, …, n, 假設編號爲i的不能站在第i個位置,求可行的方案數 (經典的錯排問題)
首先作爲一個初中生,當然可以想到容斥
爲什麼這個公式是成立的
考慮要算m(m >= 1)個人站對的情況, 算0 ~ m-1個人的時候會將當前m個人的方案多算這麼多次
既然是負的,加回去就好了,於是容斥公式成立
另一個角度
設f(n)爲n個人隨便站的方案數,g(n)爲n個人錯排的方案數,我們可以枚舉有幾個人站錯,可得
這個就是正演
但是我們好像只知道f(n),於是我們需要反演求出g(n)
各種反演
開始前先看一些性質
上面設的那個東西
前面推容斥的時候有一步是要用
k=0∑n(−1)k⎝⎛nk⎠⎞=(1+(−1))n=0n
當n=0時值爲1,否則爲0
即
k=0∑n(−1)k⎝⎛nk⎠⎞=[n==0]……(1)
首先知道一個顯然的東西
g(n)=m=0∑n[n−m==0](nm)g(m)
前面提到的性質
k=0∑n(−1)k(nk)=[n==0]……(1)
把它帶進去
g(n)=m=0∑nk=0∑n−m(−1)k(n−mk)(nm)g(m)
注意到(n−mk)(nm)的意思時從大小爲n的集合中先取m個,再從剩下的中取k個的方案數 ,和先取k個,再從剩下的當中取m個的方案數相同(n−km)(nk)
g(n)=m=0∑nk=0∑n−m(−1)k(n−mk)(nm)g(m)
=g(n)=m=0∑nk=0∑n−m(−1)k(n−km)(nk)g(m)
交換求和符號
g(n)=k=0∑n(−1)k(nk)m=0∑n−k(n−km)g(m)
然後我們發現一個很棒的東西
m=0∑n−k(n−km)g(m)=f(n−k)
所以
g(n)=k=0∑n(−1)k(nk)m=0∑n−k(n−km)g(m)
=k=0∑n(−1)k(nk)f(n−k)
換一下下標
因爲(nn−k)=(nk)
g(n)=k=0∑n(−1)n−k(nk)f(k)……(2)
二項式反演
先直接給出公式
已知
f(n)=k=0∑n⎝⎛nk⎠⎞g(k)
可得
g(n)=k=0∑n(−1)n−k⎝⎛nk⎠⎞f(k)
一般寫成
f(n)=k=0∑n⎝⎛nk⎠⎞g(k)⇔g(n)=k=0∑n(−1)n−k⎝⎛nk⎠⎞f(k)
發現和上面的2一樣誒
那就不用證了 (笑)
還有另外一個公式
f(n)=k=0∑n(−1)k⎝⎛nk⎠⎞g(k)⇔g(n)=k=0∑n(−1)k⎝⎛nk⎠⎞f(k)
這個東西看起來十分對稱,非常好記
它的證明也很簡單 根據容斥證明就好了
另外有一個更常用的公式
f(n)=k=n∑m⎝⎛kn⎠⎞g(k)⇔g(n)=k=n∑m(−1)k−n⎝⎛kn⎠⎞f(k)
證明
把右邊的代入左邊
f(n)=k=n∑m(kn)g(k)
=k=n∑m(kn)j=k∑m(jk)(−1)j−kf(j)
=j=n∑mf(j)k=n∑j(kn)(jk)(−1)j−k
注意到(jk)(kn)的意思時從大小爲j的集合中先取k個,再從取的k個中取n個的方案數 ,和先取n個,再從剩下j−n的當中取k−n個的方案數相同(jn)(j−nk−n)
因爲(j−nk−n)=(j−nj−n−(k−n))=(j−nj−k)
f(n)=j=n∑mf(j)k=n∑j(jn)(j−nj−k)(−1)j−k
=j=n∑m(jn)f(j)k=n∑j(j−nj−k)(−1)j−k
設 t = j - k
=j=n∑m(jn)f(j)t=0∑j−n(j−nt)(−1)t
看看右邊那個東西,發現是不是有點眼熟
就是性質1
k=0∑n(−1)k(nk)=[n==0]……(1)
f(n)=j=n∑m(jn)f(j)[j−n==0]
即
f(n)=j=n∑m(jn)f(j)[j==n]
f(n)=(nn)f(n)[n==n]
f(n)=f(n)
得證
一般的用法:
f(n)爲先欽定n個,然後剩下隨便搞的方案數(肯定會算重複) (不是簡單的後綴和,而是先欽定n個的所有情況,然後剩下隨便搞的和)
g(n)爲恰好n個
顯然
f(n)=k=n∑m⎝⎛kn⎠⎞g(k)
一般f(n)是很容易算的,那麼
g(n)=k=n∑m(−1)k−n⎝⎛kn⎠⎞f(k)
莫比烏斯反演
f(n)=d∣n∑g(d)⇔g(n)=d∣n∑μ(d)f(n/d)
前置知識
首先要知道 μ是個什麼函數
若d=1,μ(d)=1
若d=p1∗p2∗p3∗....∗pk,其中p爲質數且互不相同,那麼μ(d)=(−1)k
其他情況μ(d)=0
μ 的一些性質
首先它是一個積性函數
就是若 a, b互質
則滿足 μ(ab)=μ(a)μ(b)
證明很顯然啊
然後就可以線性篩了
還有一個很重要的性質
d∣n∑μ(d)=[n==1]
這個證明也很顯然,先把n質因數分解,去掉重複的質因數
假設爲 p1,p2,....,pm
上面那條式子就等價於 k=0∑m(−1)k(mk)
這條式子是不是有點熟悉, 就是上面的性質1
k=0∑n(−1)k(nk)=[n==0]……(1)
所以
k=0∑m(−1)k(mk)=[m==0]
m==0的時候n只能爲1
所以成立
證明
讓我們回憶我們證明二項式反演的時候幹了什麼?
找了個n=0時才爲1的東西,然後搞了個顯然的東西,把前一個帶入後面一個就搞出了反演
類似的我們可以搞一搞
d∣n∑μ(d)=[n==1]
顯然的
g(n)=m∣n∑[mn==1]g(m)
把上面的代入下面
g(n)=m∣n∑d∣mn∑μ(d)g(m)
注意到d∣mn就是md∣n和m∣dn是等價的
所以
g(n)=m∣n∑m∣dn∑μ(d)g(m)
同樣交換求和符號
g(n)=d∣n∑μ(d)m∣dn∑g(m)
右邊那個東西是不是有點熟悉
就是f(n)=d∣n∑g(d)
所以
g(n)=d∣n∑μ(d)f(n/d)
證畢
另一種形式
f(n)=n∣d∑g(d)⇔g(n)=n∣d∑μ(d/n)f(d)
類比二項式反演的證明
把右邊的代入左邊
f(n)=n∣d∑g(d)
=n∣d∑d∣m∑μ(m/d)f(m)
=n∣m∑t∣nm∑m/nμ(m/tn)f(m)
設m/n=T
f(n)=n∣m∑t∣nm∑Tμ(T/t)f(m)
=n∣m∑f(m)t∣T∑Tμ(T/t)
可以很容易發現
t∣T∑Tμ(T/t)=t∣T∑Tμ(t)
f(n)=n∣m∑f(m)t∣T∑Tμ(t)
右邊那個東西是不是又很熟悉
d∣n∑μ(d)=[n==1]
就是這個東西
所以
f(n)=n∣m∑f(m)[T==1]
=n∣m∑f(m)[m/n==1]
=n∣m∑f(m)[m==n]
=f(n)
證畢
一般用法
設g(n)爲gcd(x, y) == n的對數
設f(n)爲n | gcd(x,y)的對數 (1 <= x <= N, 1 <= y <= M)
顯然滿足
f(n)=n∣d∑g(d)
一般f(n)很容易算就是
f(n)=⌊nN⌋×⌊nM⌋
那麼顯然
g(n)=n∣d∑μ(d/n)f(d)
=n∣d∑μ(d/n)⌊dN⌋×⌊dM⌋
做題前還有一個東西必須要掌握 : 整除分塊
有些題推出來的式子你會發現有整除,然而對於一個數除以一段連續的數得到的結果是相同的
舉個例子
i |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
⌊10/i⌋ |
10 |
5 |
3 |
2 |
2 |
1 |
1 |
那已知左端點,如何求右端點?
右端點r=n/(n/l)
反正也不難記,先記着,後面有時間再證明(flag)
可見連續一段是相等的
for(int l=1,r;l<=n;l=r+1) {
r= n / (n / l);
計算l ~ r這段的結果
}
對於兩個數n,m的類比做一下就好了
for(int l = 1, r = 0; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
計算l ~ r這段的結果
}
兩年前自己寫的關於莫比烏斯反演的垃圾 : 莫比烏斯反演(懵逼鎢絲繁衍)
裏面有幾道題
子集反演
就是裸的容斥
FWT
之前寫過 淺談FWT
子集卷積
同上,數組多開一維記一下集合大小就好了