關於min_25篩的一些理解
如果想看如何篩個普通積性函數啥的,就別往下看了,下面沒有的(QwQ)。
下文中,所有的\(p\)都代表質數,\(P\)代表質數集合。
注意下文中定義的最小/最大質因子都是默認所有質因子本質不同。
即\(2*2*3*4*5*5\)的最小/次小質因子都是\(2\),最大/次大質因子都是\(5\)。
step1. 適用條件與思想
min_25篩用於求積性函數前綴和,即\(\sum_{i=1}^n f(i)\) 。
min_25篩相比於傳統篩法來說(如莫比烏斯反演、杜教篩),更加靈活,也沒有什么定式套路。
很多時候其實可以直接看成一個dp的模型。
這個模型可以解決很多關於質因子貢獻的問題。
它的適用條件:
- \(f(p)\)可以表示為簡單多項式。
- \(f(p^k)\) 可以快速求。
第一個條件還蠻嚴苛的。
min_25篩的思想感覺還是非常有用:篩出質數的\(f\) =====> 篩出所有數的\(f\)。
其中篩質數時,用總答案減去不合法 ; 篩所有數的時候,直接正向計算所有的答案。
step2. 篩質數的答案
min_25篩分兩步走,首先對於所有\(N = \lfloor \frac{n}{x} \rfloor\) 篩出\(\sum_{i=1}^N [i\in P] f(i)\) 。
把小於等於根號\(n\)的質數篩出來構成\(P\)集合。
又因為\(f(p)\)可以表示為簡單多項式,所以:
所以我們要求的東西其實是\(\sum_{i=1}^n [i\in P] i^k\) 。
這個東西怎么求網上博客都寫的很清楚了,設\(g(n,j) = \sum_{i=1}^n [i\in P \ or\ p_{min}(i) > p_j] f(i)\)。
然后按照\(j\)分層處理,得到:
其中\(p_j^2 \leq n\) 。
顯然,因為我們把所有數的\(f\)都當成質數的方法來算,所以只有\(g(n,P)\)是真的,其他\(g\)都是假的。
不過沒有關系,反正后面的篩法中也只需要用到\(g(n,P)\)。
但是我們也可以利用這些假的\(g\)來搞事情。
這個過程如果深入來看是什么呢?就是那個丑的不行的O(ln)埃式篩。
第\(j\)次操作后,剩余集合的\(f\)之和就是\(g(n,j)\)。
這個過程是怎么實現的呢?觀察上式右半部分,
我們每次計算了最小質因子等於當前枚舉因子\(p_j\)的函數值之和,然后把它去掉。
這可以看作 用最小質因子\(p_j\)標記了這些合數,注意是合數!
所以如果需要求一些關於最小質因子的東西的合數前綴和時,我們就可以在這里做手腳了。
光說不做假把式,求\(\sum_{i=1}^n [i\not\in P]r(p_{min}(i))i\),其中\(r(x)\)為一個關於\(x\)的函數。
咋做?
我們直接篩\(\sum_{i=1}^n [i\in P]i\)這個東西,但光篩這個是不行的,因為還要加上\(r(p_{min}(i))\)的貢獻。
注意到我們每次刪去合數的答案時,我們是用最小質因子\(p_{min}(i)\)標記的。
所以每一層\(j\)中,
\(h(j) = p_j (g(\lfloor\frac{n}{p_j}\rfloor , j-1) - g(p_{j-1},j-1))\)不就是以\(p_j\)為最小質因子的合數除掉\(p_j\)后的和嗎?
當計算\(g(n,j)\)的時候,在每一層直接加上\(r(p_j)h(j)\)即可。
如果是求質數前綴和的話......
這個東西原本的作用不就是篩質數的函數值嗎?
如果是求所有數前綴和的話......
喂喂喂,把質數的加上合數的不就是所有數了嗎?
還有邊界問題,\(g(n,0) = \sum_{i=2}^n i^k\),經典問題人人都會,差分或插值弄一下就行了。
這部分的復雜度是\(O(\frac{n^{\frac{3}{4}}}{logn})\),原因未知。
step3. 篩所有數的答案
對於后半部分,
設\(S(n,j) = \sum_{i=1}^n [p_{min}(i) \geq p_j] f(i)\),等於把\(i\in P\)的條件刪掉。
推導什么的咕咕咕網上都有。
- 質數部分答案:\(g(n,P) - \sum_{k=1}^{j-1} f(p_k)\)
- 合數部分答案:\(\sum_{k=j}^{|P|} \sum_{e=1}^{p_k^{e+1}\leq n} [f(p_k^e) S(\lfloor \frac{n}{p_k^e} \rfloor ,k+1) + f(p_k^{e+1})]\)
最后那個尾巴\(f(p_k^{e+1})\)是因為形如\(f(p^k)\)的函數值在計算中被咕咕咕了所以要補上。
這個過程可以發現一個非常有意思的事情。
對於任意一個數\(n\),我們計算到它步驟是:質因子從小往大枚舉所以:
- \(1.p_{j-1}\)一定是當前數所包含的上一個質因子。
- 2.它最大的一個質因子一定是最后枚舉到的部分。
所以如果我們求一些與最大/次大質因子有關的東西的前綴和時,我們就可以在這上面做手腳了。
先看求最大質因子特殊貢獻。
此時需要滿足一個條件:質數的后綴貢獻好求。
在求解\(S\)的過程中,我們可以強制當前這一層可選的\(p_j...p_{|P|}\)為最大質因子,
這樣就可以在算質數部分答案的時候,直接把最大質因子\(r(p_{max}(i))\)的貢獻直接加上了。
當然前提是這個后綴貢獻好加(說句實話很多時侯這個條件都不滿足)。
然后我們就處理了形如\(n = w * p_{max}\)的數的貢獻添加。
若這個數\(n = w * p_{max}^k,k>1\),我們在質數答案部分是無法添加貢獻的。
然而如果明白了min_25篩原理就可以發現,其實只需要在那個尾巴\(f(p_{k}^{e+1})\)處加上貢獻就行了。
然后如果是處理次大質因子特殊貢獻的話,其實還更好求了。
根據上述,我們知道在\(S(n,j)\)這個狀態時,我們上一層選擇的質因子一定是\(p_{j-1}\)。
所以類似的強制當前層選擇的\(p\)為最大質因子,然后使用\(p_{j-1}\)在當前層做特殊貢獻。
當然注意要特判這個數形如\(w*p_{max}^k,k>1\)的情況,此時在那個尾巴出處理一下即可。
還能干其它的嗎?
可以。
注意到對於一個數,我們在每一層枚舉的是一個本質不同的質因子。
所以我們還可以處理與特定質因子有關的前綴和計算。
當然注意時刻要記得質數的部分特殊處理,所以篩\(g\)的時候也要特殊處理一下特定質因子。
即那些特殊質因子在\(g\)中的貢獻也得是它們特殊形式的貢獻。
處理\(g\)中的特殊質因子可以按照以下步驟:
- 把特殊質因子全部拿出來排序,求它們原本形式的\(f\)、特殊形式的\(f'\)的前綴和。
- 按照一般方法把\(g\)給求出來。
- 對於每個\(g\),二分得到其包含的特殊質因子范圍,用前綴和把原來答案減掉,新答案加上。
光說不練假把式。
例:求\(\sum_{i=1}^n [gcd(i,K)=1]\mu(i)\) , 其中\(n\leq 10^{10}\) 。
說實話如果不是學了min_25篩,我這輩子都不會覺得這玩意能求。
知道了上面的套路后,這個東西就變得很簡單了,
原式即\(\sum_{i=1}^n \mu(i)\)減去包含某些特定質因子的數的貢獻,直接在min_25篩的后半部分判一下就行了。
簡單吧......
這部分的復雜度是\(O(\frac{n}{poly(logn)})\),原因同樣未知。
總結
min_25篩除了可以篩積性函數前綴和外,還有許多其他應用。
min_25篩在處理與數的因子有關的前綴和計算時,有奇效,非常的好用。
常見模型都包含在上文中了:
- 篩某積性函數前綴和 (標准形式模板題)
- 處理"最小質因子特殊貢獻"前綴和 (第一部分求\(g\)變形)
- 處理"最大值因子/次大質因子特殊貢獻"前綴和。 (第二部分求\(S\)變形)
- 處理"特定質因子特殊貢獻"前綴和。 (第一部分求\(g\)特殊處理,第二部分求\(S\)變形)
這玩意兒這么靈活感覺可以放肆出題啊.......遲早要完......瑟瑟發抖......
就醬(QwQ)。