void prime(int n) { bool flag[MAX];//0为素数 1为合数 memset(flag, 0, sizeof(flag)); for (int i = 2; i * i < n; i++) { //i为素数 if (flag[i] == false) { for (int j = i * i; j < n; j += i) { //将其倍数标记为合数 flag[j] = true; } } } }
void euler_sieve(int n) { //记录当前找到素数的数量 int sum = 0; //flag用来记录第i个数字是否为合数 true为合数 bool flag[MAX]; memset(flag, 0, sizeof(flag)); //primes用来记录每一个找到的素数 int primes[MAX]; memset(primes, 0, sizeof(primes)); for (int i = 2; i <= n; i++) { if (!flag[i]) primes[sum++] = i; for (int j = 0; i * primes[j] <= n; j++) { flag[i * primes[j]] = true; if (i % primes[j] == 0) break; } } }
\[n=Factory_{max} \ast P\]
证明如下:
1.假设P为合数,则P = P1 * P2 * ···· * Pn,其中,P1<P2<····<Pn,且Pi都为质数
因此存在一个F = Fatory * P1为n的因数,且F > Fatory,
所以和Factory是n的最大的因数矛盾,故假设不成立
2.假设P大于Factory的某个因数,不妨设P>P1
因为 Factory = P1 * P2 * ···· * Pn
因此 P * P2 * ··· * Pn 必然大于Factory
所以和Factory是n的最大因数矛盾,故假设不成立
简单举个例子:
i = 77 = 7 * 11,此时prime[]中已经储存了 3 5 7 9 …等素数
1. prime[1] = 3 ,3满足 i * 3的最小质因数的条件
2.prime[2] = 5,5满足i * 5的最小质因数条件
3.prime[3] = 7,7满足 i * 7的最小质因数条件,但此时 i % 7 == 0,因为 i 的一个质因数也是7
4.prime[4] = 11,此时就不满足 是最小质因数的条件了,i 中有比11更小的因数,因此 i * 11 中也有比11更小的因数。
欧拉筛解释思路借鉴 链接
原文:https://www.cnblogs.com/woxiaosade/p/10638818.html