【learning】洲阁筛
問題描述
快速求素?cái)?shù)處點(diǎn)值比較好求的積性函數(shù)前綴和
大致過程
Step1、求出一定范圍內(nèi)的素?cái)?shù)處點(diǎn)值之和(\(g\))
Step2、利用上面的\(g\)求出一個\(f\)然后用\(f\)求出前綴和
具體過程
(這里約定一下,在下面的內(nèi)容中用\(p\)表示一個素?cái)?shù),用\(P_i\)表示素?cái)?shù)列表中的第\(i\)項(xiàng))
這里以求\(\sum \phi(i)\)為例
首先對于素?cái)?shù)\(p\)來說,\(\phi(p)=p-1\)的,因此我們可以快速求出素?cái)?shù)處點(diǎn)值的和\(\sum \phi(p)=\sum p - \sum 1\)
這個時候我們定義
\[ \begin{aligned} g_{i,j}&=\sum\limits_{k=2}^{i}[k與P_1、P_2、P_3...P_j互質(zhì)或者就是其中的某個素?cái)?shù)]k\\ &=\sum\limits_{k=2}^{i}[k是P_j的素?cái)?shù)\ 或\ k的最小質(zhì)因子>P_j]k\\ \end{aligned} \]
初始化\(g_{i,0}=\sum\limits_{k=2}^{i} k\)
有了這個東西的話我們就可以比較快速的知道某一個范圍內(nèi)的素?cái)?shù)處點(diǎn)值的函數(shù)值和了
現(xiàn)在考慮\(g_{i,j}\)怎么求,我們考慮從\(g_{i,j-1}\)推到\(g_{i,j}\)
(這里的大體思想其實(shí)和。。之前在博客里面寫到的某道題pxp。。差不多,或者說pxp其實(shí)就是洲閣篩的前半部分)
?
將具體的含義列出來,我們要做的就是從
\[ 滿足k<=P_{j-1}的素?cái)?shù)\ 或\ k的最小質(zhì)因子>P_{j-1}的k的和 \]
推到
\[ 滿足k<=P_j的素?cái)?shù)\ 或\ k的最小質(zhì)因子>P_j的k的和 \]
看一下我們要修改的部分,對于前半部分來說應(yīng)該是加上一個\(P_j\)(如果在范圍內(nèi)的話),對于后半部分來說應(yīng)該是減去一些數(shù)(不滿足第二個條件),這些數(shù)滿足
\[ x=P_j*(一個y滿足最小質(zhì)因子>P_j,并且范圍在[P_j,\lfloor\frac{i}{P_j}\rfloor]的數(shù)) \]
于是乎我們非常愉快地發(fā)現(xiàn)后面那個括號里面的那一堆東西的和可以用回\(g\)來容斥一下表示!
\[ \sum y=g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1} \]
然后我們就可以由\(g_{i,j-1}\)推到\(g_{i,j}\)啦
\[ g_{i,j}=g_{i,j-1}-P_j(g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1}) \]
? 然而對于不同的積性函數(shù)來說,第一步的求法會有一定的差異,也許會有更加簡單的求法,反正就是要求出一個函數(shù)能夠快捷方便滴得到某一個范圍內(nèi)的素?cái)?shù)處點(diǎn)值的和就好了
如果一定要寫一個通式的話其實(shí)就是:
\[ g_{i,j}=g_{i,j-1}-F(P_j)(g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1}) \]
其中滿足\(F\)是一個完全積性函數(shù)(因?yàn)榘?span id="ozvdkddzhkzd" class="math inline">\(P_j\)提出來那步需要用到完全積性函數(shù)的性質(zhì),你并不能保證后面的那堆東西一定和\(P_j\)互質(zhì))
然后\(F\)的話具體看最開始給的要求前綴和的函數(shù)在素?cái)?shù)處的點(diǎn)值的表達(dá)式具體是啥而定,比如在這個例子里面就是\(F(x)=x\)
?
接下來是用這個\(g\)來求\(h\)
\[ h_{i,j}=\sum\limits_{k=2}^{i}[k最小質(zhì)因子>=P_j]\phi(k) \]
? (如果是別的函數(shù)的話就換一下后面的\(\phi(k)\)就可以了)
考慮這樣一種枚舉方式:
每一個數(shù)我們都可以拆成
\[ (最小質(zhì)因子)^q*一些別的東西(可以是1) \]
? 所以我們可以將上面的表達(dá)式通過枚舉素?cái)?shù)以及次方的方式寫成這樣:
\[ h_{i,j}=\sum_{q}\phi(P_j^q)\cdot h_{\lfloor \frac{i}{P_j^q}\rfloor,j+1} \]
然后就可以推\(h_{i,j}\)啦
? 然而。。。直接搞會比較麻煩。。因?yàn)檫@里為了保證復(fù)雜度還是需要上面提到的\(i>=P_j^2\)的優(yōu)化,但是這里沒有那么簡單,而是需要打上標(biāo)記
所以這里寫上另一種方式(貌似是min_25篩來著)
\[ h_{i,j}=\sum_{P_k>=P_j}\sum_{q>=1,P_k^q<=i}\phi(P_k^q)\cdot(h_{\lfloor \frac{i}{P_k^q}\rfloor,j+1}+1) \]
后面那里要\(+1\)是因?yàn)橐?span id="ozvdkddzhkzd" class="math inline">\(\phi(P_k^q)\)的部分也算上(否則都是\(一些別的東西\phi(P_k^q*一些別的東西)\))
然后直接大力搜索就可以了
邊界條件:\(i<=1\)的時候返回\(0\)
有趣的是,并不需要記憶化ovo
因?yàn)榭梢哉f明\(h\)是不會被重復(fù)調(diào)用的%%%
然后最后的答案就是\(h_{n,1}+\phi(1)\)啦
總的來說
額其實(shí)就是
\[ \begin{aligned} g_{i,j}&=g_{i,j-1}-F(P_j)(g_{\lfloor\frac{i}{P_j}\rfloor,j-1}-g_{P_j-1,j-1})\\ \\ h_{i,j}&=\sum_{P_k>=P_j}\sum_{q>=1,P_k^q<=n}f(P_k^q)\cdot h_{\lfloor \frac{i}{P_k^q}\rfloor,j+1} \end{aligned} \]
? 然后\(F\)是完全積性函數(shù),\(f\)是題目給的是一個積性函數(shù),\(F\)是根據(jù)\(f\)在素?cái)?shù)處點(diǎn)值的表達(dá)式構(gòu)造的
大概是這樣嗯ovo
哦然后時間復(fù)雜度是\(O(\frac{n^{\frac{3}{4}}}{logn})\)的至于證明的話。。不會qwq
雖然說思路真的巨無敵繞不過弄懂了的話還是比較好理解的ovo(假裝這兩句話一點(diǎn)都不矛盾)
實(shí)現(xiàn)問題
關(guān)于實(shí)現(xiàn)的話有這樣幾個比較重要的點(diǎn)單獨(dú)拿出來說一下
1.Step1中,關(guān)于\(g_{i,j}\)的求解:
題目中的\(n\)往往很大,\(i\)直接這么枚舉的話直接就愉快爆炸了
這里我們可以發(fā)現(xiàn)一個性質(zhì),就是我們其實(shí)只用關(guān)注第一維的\(i\)滿足\(i \in \{\lfloor \frac{n}{x} \rfloor|x \in [1,n]\}\)的\(g_{i...}\)值
我們將這個集合記為\(S\),那么是有\(|S|=2\sqrt n\)的,在具體實(shí)現(xiàn)的時候,我們可以先離散化一下,需要調(diào)用的時候再映射回去就好了
為什么我們可以這么做呢?看回遞推式中我們需要的\(g\)的第一維,前一部分是\(\lfloor \frac{i}{P_j} \rfloor\),這是\(\in S\)的,后一部分是\(P_j-1\),因?yàn)?span id="ozvdkddzhkzd" class="math inline">\(P_j\)我們限制是\(< \sqrt n\)的,所以\(P_j-1\in S\),所以只有\(i\in S\)的\(g_{i,...}\)才是我們實(shí)際需要算的值
2.Step2中,關(guān)于\(h_{i,j}\)的求解:
? 同樣的,如果第一維直接枚舉\(n\)的話簡直炸成煙花
這里觀察一下當(dāng)\(i<P_j\)的情況,會發(fā)現(xiàn)當(dāng)\(i<P_j^2\)的時候,能算進(jìn)來的只有\(且>=P_j且<=i\)的質(zhì)數(shù)處的函數(shù)值,所以這一部分的和可以直接用\(g_{i,max+1}-g_{P_j-1,max+1}\)表示,其中\(max\)是素?cái)?shù)列表的長度
所以枚舉的時候只枚舉到\(P_j^2<=i\),然后最后判斷一下如果存在\(i<P_j^2\)這種情況的話,就把后面整段的值一起加進(jìn)返回值里,也就是直接加上\(g_{i,max+1}-g_{P_j-1,max+1}\)
3.關(guān)于數(shù)組大小的問題。。因?yàn)殛P(guān)鍵位置的集合\(S\)的大小是\(2\sqrt n\),所以相關(guān)數(shù)組要開\(2\sqrt n\)而不是\(\sqrt n\)
代碼的話
看這題好了 Portal -->【SPOJ】DIVCNTK
轉(zhuǎn)載于:https://www.cnblogs.com/yoyoball/p/9185144.html
總結(jié)
以上是生活随笔為你收集整理的【learning】洲阁筛的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Outlook Express 错误代码
- 下一篇: 转移指令检测题9