杜教篩小結

2022-05-07 19:00:09 字數 3633 閱讀 5880

目錄**

bzoj3944 : sum

hihocoder #1456 : rikka with lattice

這個演算法十分的強... 一般就是用於卡一道數論推結論題最後的\(20\)~\(30\)分... 被迫來學習qwq

這個一般用來篩乙個積性函式在\(10^\)左右的字首和...

為了了解一下,可以看看 2023年國家候選隊**中的任之洲的積性函式求和的幾種方法

講講一些套路吧...

首先有ymy大佬告訴我的乙個神奇東西,這個似乎很有用...

若\(f*g=l\) (\(*\)為\(dirichlet\)卷積,下同) 若\(g\)和\(l\)易求(\(g,l\)的字首和) 則\(f\)易求 (\(f\)的字首和).

即\(\displaystyle l(n)-g(1)f(n)=\sum _^n g(i) f(\lfloor\frac\rfloor)\). 證明的話可以參照後面的推導來證。

\(dirichlet\)卷積 :

定義兩個數論函式\(f(x),g(x)\)的\(dirichlet\)卷積 (記作\((f*g)(x)\))

\[\displaystyle (f*g)(n)=\sum _ f(d)g(\frac)

\]

求\(\displaystyle \sum _^ \mu(i)\). (\(2\le a \le b \le 10 ^ \))

這道題乙個裸的杜教篩...求個字首和,再減一下就行了...

有乙個有用的式子\(\displaystyle \sum _ \mu(d)=[n=1]\).(這個可以見我之前那篇部落格)

解法一:

直接套用之前那個式子....

\(\mu * 1=\epsilon\) 此處\(\epsilon(x) =[x=1]\) 也就是上面那個

右邊字首和都很好求\(\displaystyle \sum _^ \epsilon(i)=1\).

然後你代入到之前那個式子就有 (令\(\displaystyle m(i)=\sum_^ \mu(i)\))

\[\displaystyle 1-m(n)=\sum _^ m(\lfloor \frac \rfloor)

\]解法二

我們來手推一下上面的式子qwq

然後就有個很顯然的式子(只有\(i=1\)時候有貢獻)

\[\therefore \displaystyle \sum_^ \sum_\mu(d)=1

\]然後更換列舉項,就是考慮每個\(d\)的對於它倍數的貢獻,然後交換和式就行了。

\[\therefore \displaystyle \sum_^ \sum_^\rfloor}\mu(j)=1

\]接下來我們就可以提出\(i=1\)時的一項,也就是\(\displaystyle \sum _^\rfloor=n} \mu(j)\)

\[\displaystyle \therefore \sum _^ \mu(i)=1-\sum_^ \sum_^\rfloor}\mu(j)

\]我們如果令\(\displaystyle m(n)=\sum_^ \mu(i)\)就有和之前那個一樣的式子了

\[\displaystyle \therefore m(n)=1-\sum_^ m(\lfloor \frac\rfloor)

\]然後我們對於這個式子就可以遞迴求解了,時間複雜度是\(\theta(n^})\).

但是一定要記得要開個雜湊表儲存一下,不然時間複雜度是個錯的!!!(來自ymy大佬的原話)

這個雜湊表可以只開\(\sqrt n\)大小,因為\(\lfloor \frac \rfloor\)只有這麼多種取值.

**我看了一下fjzzq大佬的部落格 emmm... (同屆大佬太恐怖了)

我自己寫的乙個... 注意一定要全程long long不然有詭異的錯誤....

#include #define for(i, l, r) for(register ll i = (l), _end_ = (ll)(r); i <= _end_; ++i)

#define fordown(i, r, l) for(register ll i = (r), _end_ = (ll)(l); i >= _end_; --i)

#define set(a, v) memset(a, v, sizeof(a))

using namespace std;

typedef long long ll;

bool chkmin(int &a, int b)

bool chkmax(int &a, int b)

inline ll read()

void file()

const int n = 2e6 + 1e3;

ll mu[n], limit, prime[n], cnt;

ll summu[n];

bitsetis_prime;

void mu_init(int maxn)

for (j, 1, maxn)

} }for (i, 1, maxn) summu[i] = summu[i - 1] + mu[i];

}ll size;

ll p1[n], p2[n], n;

inline ll mu_sum_(ll x)

return htr = res;

}inline ll mu_sum(ll x)

int main ()

然後在簡單講一下求\(\varphi\)(尤拉函式)的字首和吧...

求\(\displaystyle \sum_^ \varphi(i)\) 和 \(\displaystyle \sum _^ \mu(i)\). (\(n \le 2^-1\))

其實和上一道題差不多啦...多求了乙個\(\varphi\)嘛...

只要知道\(\varphi\)也有乙個類似的結論$$\displaystyle \sum_ \varphi(d)=n$$

這個我不會證明 只有乙個感性理解的方法...(來自具體數學)

你考慮所有分母為\(n\)的真分數和\(\frac\)(共有\(n\)個)

將分子和分母約去後,其他每個\(d|n\)的\(d\)都對它具有\(\varphi(d)\)的貢獻咯...

例如\(n=6\).

\[\frac,\frac,\frac,\frac,\frac,\frac

\]約分後就是

\[\frac,\frac,\frac,\frac,\frac,\frac

\]這個就比較顯然了, 應該可以寫出證明的...(太懶也太菜了..)

然後像上一題一樣的啦~ 上道題兩個解法都能用用...

\(\varphi * 1=id\)

\((id(x)=x)\) 我們令\(\displaystyle \phi(n) = \sum _ ^ \varphi(i)\).

就有乙個顯然的式子

\[\displaystyle \frac-\phi(n)=\sum_^ \phi ( \rfloor})

\]這個同上就行咯...

這題也是一道好題!~

如果想看的,就在我另一篇部落格上

無恥騙點選...

習題 杜教篩(Sum)(杜教篩)

傳送門杜教篩的板子,拿來練手 beginans sum phi i end g n 1,phi n f n h n sum phi d g frac n h n sum f d g frac 令f n sum f i h n sum h i beginh n sum h i sum sum f d ...

模板 杜教篩

杜教篩用來解決積性函式求字首和的問題。複雜度為 o n frac 適用情況 已知函式 f 求 sum f 存在 f g f 且 g,sum g,f,sum f 容易求出。常用公式 mu i n 1 varphi i id 以求 sum mu 為例。mu i n 1 sum i 1 1 1 sum i...

模板 杜教篩

杜教篩利用狄利克雷卷積來構造積性函式字首和之間的遞推式,從而利用記憶化搜尋在 n 的所有特殊點的字首和處求得 n 處的字首和。杜教篩用來處理積性函式求和問題,時間複雜度為 o n 具體證明如下 mu star 1 epsilon sum limits ni sum limits n sum limi...