从筛素数算法谈起
埃氏筛法
怎么得到$[1,N]$的所有素数,在很早很早以前(古希腊?)就有了方法。
算法的思想是用当前得到的数去筛掉他的倍数,这样每次遍历到的未被筛掉的数一定是素数。
不难发现,算法的每次会遍历$i$的所有倍数,所以算法的复杂度是调和级数的和,即$O(nlogn)$
欧拉筛法
仔细想想埃氏筛法的过程,就会发现每个数都会被它的所有素因子筛一遍,这样的操作是没有意义的,于是我们考虑一种更高效的筛法,使得每个数只被最小的素因子筛。
上述的算法由于每个数只被其素数筛掉,所以复杂度是$O(n)$的,故而又叫做线性筛法。
积性函数
定义
对于定义域在正整数的算术函数$f(n)$,若$f(1)=1$,且$f(ab)=f(a)f(b)$,其中$a,b$互质,则称$f(n)$为积性函数,如果$a,b$不互质,则称$f(n)$为完全积性函数。
性质
由算术基本定理,$f(n)$的值只由其素数因子的和其幂决定。
若$f(n)$是积性函数,$g(n)$是积性函数,那么$h(n)=f(n)g(n)$是积性函数
若$f(n)$是积性函数,那么$\sum_d|nf(d)$是积性函数
计算
如何得到积性函数往往是我们想关心的,由于上述性质来看,我们只要能够计算出$n$的最小的质数$p$的幂$k$,那么$f(n)=f(p^k)f(n/p^k)$。
所以问题便是求解一个数的最小素因子和其幂。我们发现欧拉筛法符合我们的要求,每个数只会被最小的素因子给筛掉。
由于素因子的幂不能用上述方法计算,所以只有因地制宜地计算。