演算法 Min 25篩

2022-05-20 07:23:31 字數 3135 閱讀 5662

本篇文章中使用的字母\(p\),指\(\text p \in \text\)

若函式\(f(x)\)滿足,

\(f(x)\)是積性函式

\(f(p)\)可以使用多項式表示。

已知\(f(p)\),要能在常數級的時間內計算\(f(p^x),x \in n^+\)。

min_25篩可以在\(\theta(\frac}})\)的時間複雜度內計算\(f(x)\)的字首和

或者說\(\theta(n ^ )\)?個人傾向上面那種。

分類\[\sum_^n f(i)=\sum_^nf(p),p \in prime\ + \sum_^nf(q) ,q \notin prime

\]prime指素數集合

輔助函式\(g(x,y)\)的構造與遞推

首先線性篩出質數,線性篩就不多說了(如果您線性篩都不會建議先去學習基礎演算法)

我們從小到大設\(p_i\)為從小到大排列的第i個質數

例如,\(p_1=2,p_2=3,\dots\)

設素數集合為prime,i的最小質因子為\(mpf_i\) (minimal prime fact of i)。

\(||\)為或者,即\(or\); \([a]\)表示a成立是為\(1\),否則為\(0\)

設函式\(g(x,y)\),使得

\[g(x,y)=\sum_^x[i\in prime\ ||\ mpf_i>p_y]f(i)

\]\[\sum_^x[i\in prime]

\]實際上等同於\(g(x,|prime|)\),|prime|表示\([1,x]\)之內的質數集合的大小。

首先我們要了解\(g(x,y)\)的初值

\(g(x,0)\)表示所有數的和,也就是把所有數帶入\(f(x)\)計算出的結果。

那麼接下來就是\(g(x,y)\)的遞推了。

\(p_y^2 > x\)。 此時埃篩的第\(j\)次沒有篩去任何質數(理論上第\(y\)次應該篩掉的最小質數為\(p_y^2\)),所以\(g(x,y)=g(x,y-1)\)

\(p_y^2 \leq x\)。此時埃篩篩去了所有大於\(p_y\)倍的\(p_y\)的倍數,若我們從\(g(x,y-1)\)遞推,顯然有多計算的部分,該部分就是

\[f(p_y)\times(g(\frac,y-1)-\sum_^f(i))

\]表示成公式就是:

\[g(x,y) = \left\ g(x,y-1) & p_y^2>x \\ \\ g(x,y-1)-f(p_y)\times(g(\frac,y-1)-\sum_^f(i)) & p_y^2 \leq x\end \right.

\]字首函式\(s(x,y)\)的構造與遞推

好了現在我們已經有了乙個輔助函式\(g(x,y)\),但這玩意貌似一點用都沒有....

我們設\[s(x,y)=\sum_^x[mpf_p \geq p_y]f(i)

\]講人話就是所有最小質因子大於等於\(p_j\)的\(f\)值之和。

如果我們要求\(\sum f(i),i \in [1,n]\),我們要求的東西是

\[s(n,1)+f(1)

\]鑑於所有質數對答案的貢獻我們已經完成計算,它的貢獻是

\[g(n,j)-\sum_^f(p_i)

\](我們要保證最小質因子大於等於\(p_j\)所以要把小於它的質數減去)

考慮合數對答案的貢獻,列舉合數的最小質因子和它的出現次數,然後直接計算。

合數對答案的貢獻是:

\[\sum_^ \sum_^ \leq x}s(\frac,i+1)+f(p_^)

\]總結起來就是

\[s(x,y) = g(x,|prime|) - \sum_^f(p_i) + \sum_^ \sum_^ \leq x}s(\frac,j+1)+f(p_^)

\]\(prime\)指素數集合,\(||\)表示取當前的最大質因子。

借用一下wc2019課件中的一張

[loj6053]簡單的函式

**

#include #include #define ll long long

#define maxn 1000005

#define mod 1000000007

long long sqrtn;

ll read()

// the number n, cac the sum of f(i) i belongs to [1, n]

ll n;

// primes number of primes in total

ll p[maxn], pcnt;

// g is the function g, the sum of the f(prime).

ll g[maxn];

// the number of the prime less the pn_i

ll pn[maxn];

// the id of every helpful number

ll id[2][maxn];

// prefix of p

ll prep[maxn];

// the different value of zcfk, or (n/i)

// zcfk ->

ll w[maxn], wcnt;

// is not a prime -> array in the euler sieve

bool np[maxn];

// euler sieve

void getprime(int n)

}}// cac function s

int s(ll x, int y)

return res;

}int main()

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

for (int i = 1; i <= wcnt && p[j] * p[j] <= w[i]; ++i)

// answer is s(n,1) plus f(1) = s(n,1) + 1

int ans = s(n, 1) + 1;

printf("%d\n", (ans + mod) % mod);

return 0;

}

演算法筆記 Min 25 篩

戳 這裡 加了密碼 雖然寫的可能還算清楚,但還是不公開了吧 qwq。真的想看的 私信可能會考慮給密碼 qwq。就放個板子 loj 6053 簡單的函式 f p c p xor c include define int long long using namespace std const int n...

總結 篩法 Min 25篩

對於積性函式f x f x f x 求 i 1i n f i 其中n 1011 左右 sum f i 其中n leq 10 左右 i 1 i n f i 其 中n 1 011左 右 必須滿足的條件是 當p為質數時,f p f p f p 必須能表示為乙個多項式的形式,即f p a0 a1p a2p ...

Min 25 篩學習筆記

資料和 出處 資料2資料3 打死我也不承認參考了yyb的 min 25 篩可以幹嘛?下文中未特殊說明 p 均指質數集合,p i 或 p 指某個具體質數。求一類積性函式 f x 的字首和,需要滿足 f p 可以寫成多項式的形式,或者操作一下可以寫成多項式 如例題 且 f p k 能快速求出。講真學這個...