Min 25 篩學習筆記

2022-03-19 20:28:07 字數 2662 閱讀 7094

資料和**出處

資料2資料3

打死我也不承認參考了yyb的

\(min\_25\)篩可以幹嘛?下文中未特殊說明\(p\)均指質數集合,\(p_i\)或\(p\)指某個具體質數。

求一類積性函式\(f(x)\)的字首和,需要滿足\(f(p)\)可以寫成多項式的形式,或者操作一下可以寫成多項式(如例題),且\(f(p^k)\)能快速求出。

講真學這個東西比我什麼都不會的時候學\(fft\)都累。

先求質數的貢獻。我們要求

\[\sum_^x[i是質數]f(i)$$。

我們可以設

$$g(n,j)=\sum_^[i \in p \ or\ \min(p)>p_j]f(i)\]

注意到當\(p_j^2>x\)時,\(g(n,j)=g(n,j-1)\)因為沒有新的貢獻了,所以我們只要篩到\(\sqrt n\)的質數就可以了,這也是降低複雜度的關鍵。

我們還注意到\(g(n,|p|)=\sum_^x[i是質數]f(i)\),\(|p|\)是\(\sqrt n\)內的質數集合大小。

關於\(g(n,j)\)的轉移,我們有:

\[g(n,j)=g(n,j-1)-f(p_j)[g(\frac,j-1)-\sum_^f(p_i)],p_j^2\le n

\]意思大概就是減掉所有最小質因子為\(p_j\)的貢獻,但由於\(g(\frac n,j-1)\)裡包含了質數,而\(的質數是不能算的,所以要減掉。

由於我們只需要\(g(n,|p|)\),所以下面的**是一維的,用遞推實現。注意到過程中我們只需要\(g(\lfloor\frac ni\rfloor,|p|)\),所以最多只有\(2\sqrt n\)種取值

至於實現,由於我參考了\(gsy\)的實現,痛不欲生,於是決定把他的**蒯走。這份**是篩\(f(p)=1\)的。

//這兩個鬼id就是你在杜教篩中碰到的卡常卡空間技巧,這份**你理解了這個就能看懂

//至於yl,是機房眾人mo的巨佬,所以是模數

//sq是根號n

for (int i=1,j;i<=n;i=j+1)

for (int j=1;j<=tot;++j)

for (int i=1;i<=m&&pri[j]*pri[j]<=w[i];++i)//i再往上就是所有的質數,會被後面抵消

然而敵人並沒有這麼容易就被打倒,我們還有合數沒算呢。那麼我們鼓搗乙個\(s(n,i)\)出來

\[s(n,j)=\sum_^n[\min(p)\ge p_j]f(i)

\]注意\(s(n,1)\)沒算到\(f(1)\)。答案就是\(s(n,1)+f(1)\)。

遞推式來了

\[s(n,j)=(質數的貢獻)+(合數的貢獻)

\]有沒有感覺被騙了\(qwq\),我們繼續

\[(質數的貢獻)=g(n,|p|)-\sum_^f(p_i)

\]\[(合數的貢獻)=\sum_^\sum_^\le n}s(\frac,k+1)\times f(p_k^e)+f(p_k^)

\]經過\(yl\)的指點,我可以口胡一下了,每個合數要在最小質因子處被篩到。當\(\frac n時,肯定是\(0\)就沒必要繼續了。

舉個栗子,形如\(t*p_k^3\)(其中\(t\)的最小質因子大於\(p_k\))的數會被\(s(\frac n,4)\)包含。

由於\(s\)這個函式在任何時候都不包含\(f(1)\)所以我們要手動加上\(f(p_k^2),f(p_k^3),...,f(p_k^)\)其中\(p_k^>n\)。什麼,你問我\(f(p_k)\)去哪了,這不是個質數麼。

放上loj6053簡單的函式作為例題,這裡面的\(p\)^\(c\)對於質數來說除了\(2\)以外都是\(p-1\),像個多項式。

**中\(g(x,|p|)=\sum_^x[i是質數]i\),\(h(x,|p|)=\sum_^x[i是質數]1\)

#include#include#include#include#define gt getchar()

#define ll long long

#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

inline ll in()

const int n=1e6+5,yl=1e9+7,mod=yl;

inline int mo(const int &x)

ll n,w[n];

int np[n],pr[n],tot,h[n],g[n],sp[n],id1[n],id2[n],m,sq;

void seive(int n) }}

int s(ll x,int y)

return res;

}int main()

for(int j=1;j<=tot;++j)

for(int i=1;i<=m&&1ll*pr[j]*pr[j]<=w[i];++i)

printf("%d\n",s(n,1)+1);

return 0;

}

篩與最小質因子有關的東西,用第一步篩,篩的時候順便處理一下。

篩最大次大質因子有關,考慮後面的篩,其中在亂搞一下就行了。

主要要深刻的理解min_25篩的過程,本質上是容斥?(我口胡的

多做題就明白了。

我偷偷的把ycb的題單蒯過來。

泥萌看著辦吧。

Min 25 篩 學習筆記

埃氏篩法 整除分塊 這裡有提到 1.問題模型 2.min 25 篩 3.模板題以及模板 有乙個積性函式 f 對於所有質數 p f p 是關於 p 的多項式,f p k 非常容易計算 不一定是關於 p 的多項式 求 sum f i n leq 10 1s 設集合 p 表示素數集合。設 g sum f ...

Min 25篩 學習筆記

這兒只是乙個簡單說明 概括 總結。原理見這 min 25篩用來求積性函式字首和。範圍一般是 10 要求所求積性函式在 f i 已知時,f p times i p in primes,i times p in 1,n 能快速計算。首先計算 g n,j sum if i quad i是質數 或 i的最小...

Min 25 篩學習筆記

模板 在本文中用 p 表示質數,p i 表示第 i 個質數。題目要我們求的是乙個積性函式的字首和。我們可以對於 n 內的每乙個質因子進行單獨考慮。但是這樣子的複雜度顯然過大,而這很大一部分原因是因為 n 以內的質數。因此如果我們把所有數分成質數和合數考慮,那麼在合數中的不同最小質因子個數就是 fra...