线性筛素数:
求 1 ~ n 的所有素数
运行到 i 时
(1)如果 i 没被更新,那么 i 是质数,加入素数表
证明:假设 i 是合数,设 p 是 i 的最小素因子,记 i = p * k(显然 k 的最小素因子 >= p)
运行到 k 时,p 已经被加入素数表,又因为 k 的最小素因子 >= p,所以 k * p 被更新了,矛盾
所以如果 i 没被更新,那么 i 是质数
(2)先把 i * prime[ j ] 更新为合数,然后如果 i 是 prime[ j ] 的倍数就break
这样就保证了每个被更新的合数都是由它的最小素因子更新的,于是每个合数只会被更新一次
复杂度O(n)
求1~16000的所有素数
const int MAXN = 1e6;
vector<int> prime;
bool is_prime[MAXN + 5];
bool get_prime()
{
memset(is_prime, true, sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
for(int i = 2; i <= MAXN; i++)
{
if(is_prime[i]) prime.push_back(i);
for(int j = 0; j < prime.size() && i * prime[j] <= MAXN; j++)
{
is_prime[i * prime[j]] = false;
if(i % prime[j] == 0) break;
}
}
}
线性筛欧拉函数值:
利用欧拉函数值的计算公式
const int MAXN = 1e6;
int phi[MAXN + 5];
bool get_phi()
{
for(int i = 1; i < MAXN; i++)
phi[i] = i;
for(int i = 2; i < MAXN; i++)
if(phi[i] == i)
for(int j = i; j < MAXN; j += i)
phi[j] = phi[j] / i * (i - 1);
}
求 1 ~ n 每个数的最大素因子
先把factor初始化为0
运行到 i 时
(1)factor[i] 不等于0,continue
(2)factor[i] 等于0,那么 i 是质数,把所有i的倍数的factor都更新为 i
存在重复标记的问题,待完善