模板:杜教筛(莫比乌斯反演、数论)
所謂杜教篩,就是dms教給我們的篩
(逃)
前言
與其說算法,不如說是技巧。
可以在低于線性的時間復(fù)雜度(準(zhǔn)確的說是 O(n23)O(n^{\frac{2}{3}})O(n32?))內(nèi)完成對積性函數(shù)的前綴和計(jì)算。
解析
考慮求函數(shù) fff 的前綴和:
S(n)=∑i=1nf(i)S(n)=\sum_{i=1}^nf(i)S(n)=i=1∑n?f(i)
尋找另一個函數(shù) ggg,設(shè) h=f?gh=f*gh=f?g,那么有:
∑i=1nh(i)=∑i=1n∑d∣ig(d)f(id)=∑d=1ng(d)∑i=1?nd?f(i)=∑d=1ng(d)S(?nd?)\sum_{i=1}^nh(i)=\sum_{i=1}^n\sum_{d|i}g(d)f(\frac i d)\\=\sum_{d=1}^ng(d)\sum_{i=1}^{\lfloor\frac n d\rfloor}f(i)\\=\sum_{d=1}^ng(d)S(\lfloor\dfrac n d\rfloor)i=1∑n?h(i)=i=1∑n?d∣i∑?g(d)f(di?)=d=1∑n?g(d)i=1∑?dn???f(i)=d=1∑n?g(d)S(?dn??)。
嘗試湊出 S(n)S(n)S(n):
g(1)S(n)=∑d=1ng(d)S(?nd?)?∑d=2ng(d)S(?nd?)=∑d=1nh(d)?∑d=2ng(d)S(?nd?)g(1)S(n)=\sum_{d=1}^ng(d)S(\lfloor\dfrac n d\rfloor)-\sum_{d=2}^ng(d)S(\lfloor\dfrac n d\rfloor)\\=\sum_{d=1}^nh(d)-\sum_{d=2}^ng(d)S(\lfloor\dfrac n d\rfloor)g(1)S(n)=d=1∑n?g(d)S(?dn??)?d=2∑n?g(d)S(?dn??)=d=1∑n?h(d)?d=2∑n?g(d)S(?dn??)
后面的 SSS 就可以遞歸求解了。
時間復(fù)雜度
按照上面的式子,可以寫出時間復(fù)雜度的遞推式:
T(n)=O(n)+∑i=2n(T(i)+T(ni))T(n)=O(\sqrt n)+\sum_{i=2}^{\sqrt n}(T(i)+T(\frac n i))T(n)=O(n?)+i=2∑n??(T(i)+T(in?))
由于再往下遞歸就是高階小量,我們只需要展開一層:
T(n)=O(n)+∑i=2n(O(i)+O(ni))T(n)=O(\sqrt n)+\sum_{i=2}^{\sqrt n}(O(\sqrt i)+O(\sqrt \frac n i))T(n)=O(n?)+i=2∑n??(O(i?)+O(in??))
由于 O(i)+O(ni)≥O(2n)=O(n14)O(\sqrt i)+O(\sqrt \frac n i)\ge O(2\sqrt{\sqrt n})=O(n^{\frac 1 4})O(i?)+O(in??)≥O(2n??)=O(n41?),所以總的復(fù)雜度大概是 O(n34)O(n^{\frac 3 4})O(n43?)。
考慮先用線性篩預(yù)處理出一部分前綴和。
由于算法本身根號分治就有 O(n)O(\sqrt n)O(n?),所以不妨設(shè)預(yù)處理的范圍 m>nm>\sqrt nm>n?。
那么時間復(fù)雜度就變成了:
T(n)=O(m)+O(n)+∑i=2?nm?T(?ni?)=O(m)+O(n)+∑i=2?nm?O(?ni?)=O(m)+O(n)+∫0nmnx=O(m)+O(n)+f(nm)(f(x)=nx)=O(m)+O(n)+O(nm)≥O(n23)T(n)=O(m)+O(\sqrt n)+\sum_{i=2}^{\lfloor\frac n m\rfloor}T(\lfloor\frac n i\rfloor)\\=O(m)+O(\sqrt n)+\sum_{i=2}^{\lfloor\frac n m\rfloor}O(\sqrt{\lfloor\frac n i\rfloor})\\=O(m)+O(\sqrt n)+\int_0^{\frac n m}\sqrt{\frac n x}\\=O(m)+O(\sqrt n)+f(\frac n m)(f(x)=\sqrt{nx})\\=O(m)+O(\sqrt n)+O(\frac{n}{\sqrt m})\\\ge O(n^{\frac 2 3})T(n)=O(m)+O(n?)+i=2∑?mn???T(?in??)=O(m)+O(n?)+i=2∑?mn???O(?in???)=O(m)+O(n?)+∫0mn??xn??=O(m)+O(n?)+f(mn?)(f(x)=nx?)=O(m)+O(n?)+O(m?n?)≥O(n32?)
當(dāng) m=n23m=n^\frac 2 3m=n32? 時取等。
應(yīng)用
如何使用杜教篩呢?
舉個例子:計(jì)算 ∑i=1nμ(i)\sum_{i=1}^n\mu(i)∑i=1n?μ(i)。
我們把剛才的核心式子拿下來:
g(1)S(n)=∑d=1nh(d)?∑d=2ng(d)S(?nd?)g(1)S(n)=\sum_{d=1}^nh(d)-\sum_{d=2}^ng(d)S(\lfloor\dfrac n d\rfloor)g(1)S(n)=d=1∑n?h(d)?d=2∑n?g(d)S(?dn??)
首先,我們需要使 ∑d=1nh(d)\sum_{d=1}^nh(d)∑d=1n?h(d) 可以很容易的求出來,不然就沒有意義了。
同時,我們最好也能讓 ggg 函數(shù)簡單一些。
想到:μ?1=e\mu*1=eμ?1=e。
令 g=1,h=eg=1,h=eg=1,h=e,就很好的滿足了我們的要求。
式子變成:
S(n)=1?∑d=2nS(?nd?)S(n)=1-\sum_{d=2}^nS(\lfloor\dfrac n d\rfloor)S(n)=1?d=2∑n?S(?dn??)
非常簡潔,直接求解即可。
實(shí)現(xiàn)上,需要開一個 map 或者哈希表進(jìn)行記憶化。
代碼
ll getmu(int n){if(n<=w) return sum1[n];if(mp1.count(n)) return mp1[n];ll ans=1;for(ll l=2,r;l<=n;l=r+1){assert(n/l);r=n/(n/l);ans-=(r-l+1)*getmu(n/l);}return mp1[n]=ans; }總結(jié)
以上是生活随笔為你收集整理的模板:杜教筛(莫比乌斯反演、数论)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在电脑上打出韩国字如何用电脑输入韩语
- 下一篇: 电脑卡顿时不要暴躁!从这4个方面着手,运