杜教筛&Min_25筛学习笔记

杜教筛

这个东西已经咕了差不多半年QAQ
然后现在才开始写.

有的时候,我们需要完成这样一个问题.
\(\sum_{i=1}^nf(i)\).其中\(f\)是积性函数.
\(n\leq 10^7\)时,可以用线性筛解决这个问题.
然而,起源于\(Project Eular\)的这个黑科技可以把\(n\)的范围扩展到\(10^{11}\)左右.

考虑狄利克雷卷积.
假设\(f*g=h\),那么写成狄利克雷卷积的形式,就是
\[\sum_{i=1}^nh(i)=\sum_{i=1}^n\sum_{d|i}f(i)g(\frac{i}{d})\\ =\sum_{d=1}^ng(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)\\ =\sum_{d=1}^ng(d)S(\lfloor\frac{n}{d}\rfloor)\\ 把第一项拉出来,得\\ g(1)S(n)=\sum\limits_{i=1}^{n}g(i)S(\lfloor\frac{n}{i}\rfloor)-\sum\limits_{i=2}^{n}g(i)S(\lfloor\frac{n}{i} \rfloor) \]
考虑到\(\lfloor\frac{n}{d}\rfloor\)只有\(\sqrt n\)种取值,于是记忆化搜索一波,美滋滋.
因此,只要可以快速求\(h\)的前缀和与\(g\),就可以快速求\(f\)的和.

时间复杂度大约是\(O(n^{\frac{3}{4}})\),可以用积分证.

下面举几个栗子.

莫比乌斯函数

我们知道\(\mu*1=e\),而\(\sum h=1\),因此就很好求啦.
在存储上也有一个小优化,无需\(map\).考虑到求出的每个\(S(x)\),\(x\)都是\(n\)的因数且\(\frac{n}{x}\)不大,因此只需如下代码即可.

LL calc_miu(int x){
    if(x
欧拉函数

我们知道\(\varphi*1=id\),因此\(\sum h=\frac{n*(n-1)}{2}\),就很好求啦.
代码如下

LL calc_phi(int x){
    if(x

Min_25筛

待UPD

转载于:https://www.cnblogs.com/Romeolong/p/10062106.html

你可能感兴趣的:(杜教筛&Min_25筛学习笔记)