前言
最近学数论,我是真的绝望,欧拉筛法也只能靠背代码勉强凑合凑合,但在我社CSQ大佬的帮助下,我理解到了其中神奇的奥妙
正题
欧拉筛法是一种可以筛出质数,欧拉函数,约数个数和约数和的筛法
那么我们就对这些问题逐一进行讲解
在这之前,我们先说几个东西:
1、每一个大于等于2的正整数 n n n,都有 n = p 1 w 1 p 2 w 2 … p m w m n=p_1^{w_1}p_2^{w_2}…p_m^{w_m} n=p1w1p2w2…pmwm( p 1 p_1 p1到 p m p_m pm按升序排列)
2、正整数 n n n的欧拉函数 p h i ( n ) = n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) … ( 1 − 1 p m ) = p 1 w 1 − 1 ( p 1 − 1 ) ∗ p 2 w 2 − 1 ( p 2 − 1 ) ∗ … ∗ p m w m − 1 ( p m − 1 ) phi(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})…(1-\frac{1}{p_m})=p_1^{w_1-1}(p_1-1)*p_2^{w_2-1}(p_2-1)*…*p_m^{w_m-1}(p_m-1) phi(n)=n(1−p11)(1−p21)…(1−pm1)=p1w1−1(p1−1)∗p2w2−1(p2−1)∗…∗pmwm−1(pm−1)
3、正整数 n n n的约数个数 d ( n ) = ( 1 + w 1 ) ( 1 + w 2 ) … ( 1 + w m ) d(n)=(1+w_1)(1+w_2)…(1+w_m) d(n)=(1+w1)(1+w2)…(1+wm)
4、正整数 n n n的约数和 s ( n ) = ( 1 + p 1 + p 1 2 + … + p 1 w 1 ) ( 1 + p 2 + p 2 2 + … + p 2 w 2 ) … … ( 1 + p m + p m 2 + … + p m w m ) s(n)=(1+p_1+p_1^2+…+p_1^{w_1})(1+p_2+p_2^2+…+p_2^{w_2})……(1+p_m+p_m^2+…+p_m^{w_m}) s(n)=(1+p1+p12+…+p1w1)(1+p2+p22+…+p2w2)……(1+pm+pm2+…+pmwm)
质数
思路
筛质数是一个相对简单的内容,在普通的筛法中,我们知道当一个数 i i i为质数时,可以筛掉所有 i i i的倍数
但在欧拉筛法中,我们会进行一定的优化,那么外层循环枚举 i i i,判断 i i i是否为质数;内层循环枚举 j j j,这个 j j j实质上就是枚举第 j j j个质数,筛掉 i ∗ p r i m [ j ] i*prim[j] i∗prim[j],重点就是接下来的步骤:
如果 i % p r i m [ j ] = = 0 i\%prim[j]==0 i%prim[j]==0,我们就要 b r e a k break break掉,这是因为我们筛素数是肯定是希望每一个数都能被它的最小质因子筛掉,当 i % p r i m [ j ] = = 0 i\%prim[j]==0 i%prim[j]==0时,就相当于 i = p r i m [ j ] ∗ k ( k 为 一 个 正 整 数 ) i=prim[j]*k(k为一个正整数) i=prim[j]∗k(k为一个正整数),那么如果我们继续往后枚举到了一个质数 p r i m [ m ] prim[m] prim[m],就要筛去 i ∗ p r i m [ m ] i*prim[m] i∗prim[m],也就是 p r i m [ j ] ∗ k ∗ p r i m [ m ] prim[j]*k*prim[m] prim[j]∗k∗prim[m],因为我们枚举的质数是从小到大的,所以 i ∗ p r i m [ m ] i*prim[m] i∗prim[m]的最小质因子应该是 p r i m [ j ] prim[j] prim[j],若继续枚举,就会出现冗余的计算
代码
inline void sieve(int x) {
for(reg int i = 2;i <= x;i ++) {
if(! vis[i])
prim[++ len] = i;
for(reg int j = 1;j <= len && i * prim[j] <= x;j ++) {
vis[i * prim[j]] = 1;
if(i % prim[j] == 0)
break;
}
}
}
欧拉函数
思路
我们知道欧拉函数是这样的: p h i ( n ) = p 1 w 1 − 1 ( p 1 − 1 ) ∗ p 2 w 2 − 1 ( p 2 − 1 ) ∗ … ∗ p m w m − 1 ( p m − 1 ) phi(n)=p_1^{w_1-1}(p_1-1)*p_2^{w_2-1}(p_2-1)*…*p_m^{w_m-1}(p_m-1) phi(n)=p1w1−1(p1−1)∗p2w2−1(p2−1)∗…∗pmwm