除了处理质数的问题,线性筛还可以较为高效的处理数论函数,虽然有杜教筛这个东西,关键的时候还是要线性筛救命
1.筛质数
先看看线性筛本体,它的功能是判断质数,以及求最小质因数
1.记录minfactor,prime
2.对cur一直用prime数组筛去剩下的合数
这里判断质数的标准很简单,就是判断一个数的最小质因数是否就是它本身
由于是求最小质因数,(prime[j]<=minfact[i]),这样可以证明每个合数仅被它的最小质因数筛到,保证线性复杂度
2.求(phi(n))
(phi(p)=p-1),利用这个性质,可在判断质数的同时筛出它的欧拉函数
由欧拉函数的积性性得,(phi(mn)=phi(m)phi(n))
当(minfact[i]=prime[j]),即有重复质因子时,(phi(p^k)=p^{k-1}(p-1)),乘上p即可
不然乘上(p-1)
3.求(mu(n))
(mu(p)=-1),利用这个性质,可在判断质数的同时筛出它的莫比乌斯函数
当(minfact[i]=prime[j]),即有重复质因子时,(mu(n)=0)
不然乘上(mu(n)=-mu(i))
4.求(d(n))
比前面的两个函数要麻烦一些,求(d(n))要记录n中最小质因子数(cnt[n])
对于质数,(cnt[n])很显然等于1
接着考虑(d(n)),(n=Pi^k_{i=1}p_i^{a_i}),(d(n)=Pi^k_{i=1}(p_i+1))
如果(minfact[i]=prime[j]),由牛顿二项式定理得,(d(n)=d(i)/(cnt[i]+1)*(cnt(i)+2))
不然(d(n)=d(i)*d(prime[j]))
5.求(sigma(n))
类似于求(d(n)),不过这次要记录一个数组(sum[i]=Sigma_{i=0}^kp^i),p表示n的最小质因数,(sum[i])表示最小质因数的k次幂下的和
对于质数,(sum[i])很显然等于p+1
接着考虑(sigma(n)),(sigma(n)=Pi_{i=1}^kSigma_{j=0}^{a_i}p^j_i)
如果(minfact[i]=prime[j]),在求和式中加入一项(p^{k+1}),等同于乘((sum[i]*p+1)/sum[i])
不然(sigma(n)=sigma(i)*sigma(prime[j]))
可以发现,所有上述求数论函数的方法都依靠他们的积性性,并通过每个数的最小质因数来确定计算方法
能用原本判断质数的线性筛求数论函数就是利用了对最小质因数的分析
虽然杜教筛不算很难,但线性筛好写好想,功能全面,不失为一个很好的备用方案