upd:正在寫一篇復習向的文章,之后貼鏈接,可以作為這篇文章的一個補充。
upd:寫好啦,戳這里。新寫的這篇復習向文章QwQ,可以當做一個補充來看吧。不過新寫的文章也有我新的理解吧。
Part0
最近一直在搞這些東西
做了將近20道題目吧
也算是有感而發
寫點東西記錄一下自己的感受
如果您真的想學會莫比烏斯反演和杜教篩,請拿出紙筆,每個式子都自己好好的推一遍,理解清楚每一步是怎么來的,並且自己好好思考。
Part1莫比烏斯反演
莫比烏斯反演啥都沒有,就只有兩個式子(一般只用一個)
原來我已經寫過一次了,再在這里寫一次
就只寫常用的那個吧
基本的公式
對於一個函數\(f(x)\)
設\(g(x)=\sum_{x|d}f(d)\)
那么
這個有什么用?
似乎太有用了一點
隨手搞道題目來說吧
求$$\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1]$$
這個東西很直接,
所以我們設$$f(x)=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=x]$$
根據莫比烏斯反演可以得到
\(g(x)\)是什么東西?
直接把\(x\)除到上面去
\([1|gcd]\)顯然成立的
所以\(g(x)=[\frac{n}{x}][\frac{m}{x}]\)
可以\(O(1)\)計算
所以,\(f(1)\)可以\(O(n)\)計算
一起推下式子
莫比烏斯反演的套路太多了
我們再來看兩道題目
Crash的數字表格
jzptab
這兩題按照順序看嗷
具體的過程直接看我博客里面寫的東西
我們發現這兩道題一模一樣
但是下面的那道題目可以做到單次詢問\(O(\sqrt n)\)
他多干了什么???
這個問題,我們自己再來重新推一下
不過找個容易點的東西
這個肯定沒有前面我給的例子的莫比烏斯反演那么直接
但是我們觀察一下,\(gcd\)的取值有哪些??
\(1~n\)(假設\(n<m\))
那么,我們可以把\(gcd\)相同的項合並
所以,我們枚舉\(gcd\)的值
后面的那一部分是不是想到了前面推出的東西???
所以先把\(d\)直接除上去
\(n/d\)和\(m/d\)不要想太多,你就當成\(x\)和\(y\)
不就是上面推過的第一個例子??
把這一截放回我們要求的式子里面去
把\(x,y\)還是寫成原樣吧
是不是\(n/d\)可以數論分塊
而在計算后面的東西的時候,\(\frac{n/d}{i}\)也可以數論分塊??
所以這個時候的復雜度是\(O(n)\)
與之相對應的就是上面Crash的數字表格的\(O(n)\)做法
可是,像下面那個\(O(\sqrt n)\)是怎么做的呢?
那我們就繼續推一步
我們是不是可以直接對\(\frac{n}{id}\)分塊呢?
所以,我們設\(T=id\)把\(id\)換一下
這個時候,比較關鍵的一步
把\(T\)提出來
為什么是這個??
我們來分析一波
首先每一個\(T\)一定對應\([\frac{n}{T}][\frac{m}{T}]\)
這一項之和\(T\)有關,所以可以提出來
這個時候考慮對於每一個\(T\),什么樣的\(i\)和\(d\)會給他產生貢獻呢?
最顯然的一點,\(d\)是\(T\)的一個因數
看到上面的式子,我們不難發現會貢獻一個\(d\)的什么東西
后面的是什么?\(\mu(i)\)
繼續想想,既然\(T=id\),我們枚舉了一個\(T\),
又知道\(d\)是\(T\)的一個因子了,所以\(i=\frac{T}{d}\)
所以,就有了上面把\(T\)拿出來的式子
前面的東西看起來可以數論分塊
但是這樣子后面的東西怎么辦?
不可能\(O(\sqrt n)\)暴力枚舉呀
沒錯,當然不需要暴力枚舉
我們發現后面的東西也是一個積性函數(因為他是兩個積性函數的狄利克雷卷積)
所以它是可以線性的篩出來的
到這里,前面對於\(T\)數論分塊
后面的前綴和可以\(O(n)\)線性篩預處理出來
此時單次詢問整體的復雜度就是\(O(\sqrt n)\)
對了,不要思想江化
后面那個東西如果不能夠直接線性篩
那就不要線性篩了,
只要復雜度允許,暴力篩也是很可以的
其實,如果我們繼續觀察,很容易知道一點:
\(\sum_{d|T}d\mu(\frac{T}{d})=\varphi(T)\)
upd:原來底下的證明是假的,已經刪掉了,這里用容斥的方法很容易證明,考慮到\(\mu\)是容斥系數就可以很容易的知道上述式子的組合意義。
我們知道\((1*\varphi)(i)=i\)
還知道\((1*\mu)(i)=e\)
其中\(1\)是\(f(x)=1\)
\(e\)是\(f(x)=[x=1]\)
\(id\)是\(f(x)=x\)
所以這個東西當然可以線性篩啦。
莫比烏斯反演差不多就到這里啦
我們經歷的復雜度從\(O(n^2)\)的暴力
推一步之后變成了\(O(n)\)
再變成了\(O(\sqrt n)\)
莫比烏斯反演的關鍵步驟也就是兩步
首先是化簡式子,寫成莫比烏斯反演的形式
然后就是怎么處理前綴和,數論分塊等東西的問題
這些能夠解決好,莫比烏斯反演的題目就很好解決啦
Part2線性篩
當然是怎么各種線性篩東西啦
線性篩最重要的一點:
每個數一定,也只會,被他的最小質因子給篩到
說白點,比如說\(72=2*2*2*3*3\)
他就會被他的最小質因子給篩到
也就是\(2*36\)時被篩到
所以,一般線性篩如果要存儲其他的東西來篩的話
一定是記錄最小質因子的東西
大概的寫一下幾個積性函數:
\(\mu\)莫比烏斯函數
這個怎么篩應該都會吧
\(\varphi\)歐拉函數
怎么篩應該也很明顯吧。
\(d\)約數個數
這個怎么篩?
考慮唯一分解定理:
\(x=\prod p_i^{ai}\)
那么\(d(x)=\prod (ai+1)\)
記錄一下最小質因子的個數
每次就先把原來的除掉,再把\(+1\)后的個數乘上就好啦
\(\sigma\)約數和
還是唯一分解定理
\(x=\prod p_i^{ai}\)
\(\sigma(x)=\prod (\sum_{j=0}^{ai}p_i^j)\)
記錄一下最小質因子的上面那個式子的和
以及這個因子的\(ai\)次冪
每次也是先除掉再乘上新的
\(a^k\) \(k\)次冪
把這個東西寫進來,只是為了提醒一下
\(a^k\)這種東西是一個完全積性函數,也是可以丟進去篩的
\(inv\)乘法逆元
沒啥,一樣的,乘法逆元也是完全積性函數
蛤,我知道可以\(O(n)\)遞推
只是寫一下而已
我比較懶,不想把板子蒯過來
直接把ppl的鏈接給你們嗷(雖然他的代碼風格我覺得很丑)
Part3杜教篩
來個栗子
線性篩\(O(n)\)復雜度,美滋滋
好的,我知道了
來一個很\(interesting\)的題目???
我當然知道你會線性篩
所以\(n<=10^9\)
杜教篩是蛤?
比如說。。
我們現在要求一個積性函數\(f(i)\)的前綴和\(S(i)\)
也就是說\(S(n)=\sum_{i=1}^nf(i)\)
現在很不好算呀
怎么辦??
這個時候,就來杜教篩套路一波
我再來找個積性函數\(g(i)\)(不知道是啥)
讓\(g\)和\(f\)做一個卷積
再求一下卷積的前綴和
把\(d\)給提出來
如果仔細想想
我們就會有這個式子:
前面的東西是狄利克雷卷積
如果狄利克雷卷積的前綴和非常好算的話
那么我們就可以對后面的東西進行數論分塊
然后遞歸計算。
提醒一句:
一定要記憶化,一定要記憶化,一定要記憶化
回到栗子
\(\sum_{i=1}^n\mu(i)\)
把杜教篩的公式套路式子找過來蛤
看到了\(\mu\)想一個積性函數,讓他們的狄利克雷卷積前綴和很好算
我們知道
也就是說
\(e\)的前綴和是啥?
當然是\(1\)了
所以,取\(g(x)=1\)
這樣子的話,首先線性篩出一部分的\(\mu\)的前綴和
然后來一波記憶化搜索美滋滋
再來個栗子把
把上面的\(\mu\)換成\(\varphi\)
我們還是知道
所以,如果是\(\varphi\)的話
就令\(g(x)=1\)
所以,
多好的套路
但是,不要被套路給套死啦
面對不同的函數
一定要考慮清楚\(g\)是啥
好的\(g\)能讓你的程序更加好算
Part4我也不知道為什么要加上這一部分
好啦
上面好好地寫了一下莫比烏斯反演和杜教篩
是不是覺得很簡單
當然,莫比烏斯反演和杜教篩當然可以混在一起
莫比烏斯反演推柿子
杜教篩求前綴和
一點也不矛盾
既然我也不知道最后這部分干啥
那就找一堆題目來吧
歡迎查我水表
算了
還是把水表給你們把
莫比烏斯反演的水表
杜教篩的水表
最后,說幾句話
不要因為有了杜教篩和線性篩
就天天想着怎么篩
篩不了就滾去寫暴力
埃氏篩法很不錯
暴力枚舉因數也很不錯
最后,一句最經典的話作為結尾
騙分過樣例,暴力出奇跡
