杜教筛

这是一个玄学的东西……

杜教筛能够在$O(n^{\frac{2}{3}})$内算出积性函数的前缀和

原理:

对于一个积性函数,要求

$$S(n)=\sum_{i=1}^n f(i)$$

需要根据函数 $f(n)$ 的性质,构造一个 $S(n)$ 关于 $S(\lfloor\frac{n}{i}\rfloor)$ 的递推式,如下例。

找到一个合适的数论函数 $g(n)$:
$$\sum_{i=1}^n\sum_{d|i}f(d)g\Big(\frac{i}{d}\Big)=\sum_{i=1}^n g(i)S(\lfloor\frac{n}{i}\rfloor)$$

可以得到递推式:
$$g(1)S(n)=\sum_{i=1}^n(f*g)(i)-\sum_{i=2}^n g(i)S(\lfloor\frac{n}{i}\rfloor)$$

$f*g$ 为狄利克雷卷积,$(f*g)(x)=\sum_{d|n}f(d)g(\frac{n}{d})$

时间复杂度,不会证啊!QAQ 你只要知道它很快就好了。

假如可以快速对 $(f*g)(i)$ 以及 $g(i)$ 完成求和,那么就可以根据的$\lfloor\frac{n}{i}\rfloor$取值进行分段,计算一个 $S(n)$ 的复杂度即为 $O(\sqrt{n}) $。

参见博客戳这里

实现:

很容易想到记忆化深搜,然后用 map 存值,代码如下:

 1 int get_mu(int x){
 2     if(x<=1700000)return mu1[x];
 3     if(mu2.count(x))return mu2[x];
 4     int ans=1;
 5     for(int i=2,pos;i<=x;i=pos+1){
 6         pos=x/(x/i);
 7         ans-=get_mu(x/i)*(pos-i+1);
 8     }
 9     return mu2[x]=ans;
10 }

先用线性筛求出 $n^{\frac{2}{3}}$ 的前缀和可以降低时间复杂度!

posted @ 2018-08-03 09:22  ezoiLZH  阅读(218)  评论(0编辑  收藏  举报