线性筛法是O(n),不然它就不叫线性。
为什么线性呢?
先上代码:
fo(i,2,maxn) {
if(!bz[i])
p[++p[0]]=i;
fo(j,1,p[0]) {
if(maxn / p[j] < i) break;//出界处理,用除法防止爆炸。
int k=i*p[j];
bz[k]=1;
if(i % p[j] == 0) break;//!!!线性的关键之处,就比普通筛法多了这一句话。
}
}
普通筛法:
对于普通的约瑟夫筛法,其实只是少了一句“if(i % p[j] == 0) break;”
普通约瑟夫筛法的时间十分好求,就是每个数约数的个数的和,因为每个数都会被它所有的约数筛过一次。
可以粗略地估计为O(n log n)
线性筛法:
首先要明白的是:
在枚举已求出的质数去筛其他数的时候,p[j]一定是i*p[j]最小的质因子。
如果说i有更小的的质因子,那么在前面的循环就会因为“if(i % p[j] == 0) break;”而退出循环。
这样每个数只会被它最小的质因子筛去,时间复杂度是O(n)的。
一些用法:
对于积性函数,在p[j]不是i的约数时直接相乘,如果是,就需要知道这个函数的解析式。
积性函数,根据个人的经验,函数值肯定可以通过分解质因数之后用各个质因子和指数乱搞出来,否则它就不叫积性函数。
当然后时候比较难退,参考下面不是积性函数的方法。
假设要求∑ni=1∑mj=1f(gcd(i,j)),其中f是一个积性函数,多组询问。
经过若干变形后都可变成∑nT=1⌊nT⌋⌊mT⌋∑p|Tf(p)∗μ(T/p)
对⌊nT⌋⌊mT⌋分块,那么需要预处理∑p|Tf(p)∗μ(T/p)的前缀和,这里如果死磕线筛就要把握好性质,比如要使μ(T/p)大于零,则p的各个质因子的指数与T的对应的质因子的指数的差就不能超过1,否则根据定义,μ=0,这样去一个个推就行了。
杜教筛:
……

本文详细介绍了线性筛法的基本原理与实现方法,并对比了其与普通筛法的区别。通过具体实例解释了线性筛法如何实现O(n)的时间复杂度,以及在积性函数求解中的应用。
3383

被折叠的 条评论
为什么被折叠?



