筛是一种针对特殊的积性函数的筛法,可以在的复杂度内筛出某函数的前缀和,在中应用不及杜教筛,但是仍然有学习价值。
筛的要求:
对于有明确定义,并且比较好求。
该函数在时,为完全积性函数,或者可以拆成几个完全积性函数。
由此可见,上述要求较为苛刻,这种函数除非特意构造,不然很难自然的出现在题目之中。
但是筛相比杜教筛的优势是,不用去特意构造狄利克雷卷积,也就不依赖数论函数(等)。
实现:
Part1:处理质数部分对的贡献
因为为完全积性的,我们构造一个,使得在任何地方的定义都是与在质数时的定义相同,我们求出的前缀和,然后依次筛掉合数部分的值,剩下的部分和是等价的。
我们利用类似于埃氏筛的思想,依次筛掉最小质因子为的贡献,因为最小质因子一定,我们只要筛出的质数就可以了。
此处比较神仙:
我们设
考虑把变成,其实就是要筛掉作为最小质因子的数的贡献,而是完全积性的,我们可以直接提出一个,枚举其他因子:
但是这样会算多,因为,而定义中会包含的,所以到也会被算进去,在这部分中,就不是最小质因子了,和定义不符,需要减去。
所以我们要预先处理出的,记为,表示前小的质数的值之和。
于是转移就可以写成
可以发现这个东西可以滚动数组,我们只要预先求出所有形如的函数值(就是前项的前缀和),然后枚举从大到小,直接更新即可。
Part2 依次加入合数对的贡献
我们记表示筛完了合数后的的和,显然这东西就等于质数部分的之和。
然后这里再次神仙一波:
我们设
注意:此处的定义于上面不同,质数将不再无脑合法,且变成了。
然后我们枚举最小质因子及其次数,有转移:
看起来蛮恐怖的,其实联系实际意义想还好,的贡献已经在前面了,只是把单含这个质因子的数和含其他因子的数分开算了而已,当的时候显然也,就没有必要枚举了。
注意:不管是筛还是,的贡献最好单独计算。
代码实现
写一下处理所有形如的的前缀和这部分。
这里因为开不下数组,我们离散化一下,对于的直接记录下标,对于,我们记录这个即可。
注意:我们处理这个时使用数论分块,对于我们记录的为分块时的,因为我们引用下标的时候用就可以得到这个。
另外一个需要记得的是,枚举最小质因子及其次数,要到就停止。
题目
[Loj6053]简单的函数
此处注意到并不是完全积性的,我们令,并令表示前个素数之和。
我们按照上面的方法设出和等到筛完了和后,我们发现他们的定义是:
有了这两个我们就可以筛了:
1 |
|
[luogu5325]筛模板
题意:求,,为积性函数。
考虑把拆成和,其实就是和。
这样当的时候他们就是完全积性的,和上面类似的方法筛就可以了。
但是要注意在处理的时候可能会爆,得记得取模。
1 |
|
[SPOJ20173]DIVCNT2 - Counting Divisors (square)
题意:求
暴力筛。考虑,,我们只要设最后再乘上个即可,复杂度。
大概就是拆成
然后对于和,大于的现场暴力,小于的事先预处理出来,复杂度就是,证明可以参考杜教筛。
但是我们会发现因为某种玄妙原因,不管是否记忆化这个方法都跑不过筛,并且这种筛法空间是的,全面被吊打。