埃氏筛法(复杂度O(NlogNlogN))
埃氏筛法简单说就是先列出2-n的值,其中遇见第一个素数2,于是将所有2的倍数删去,继续往下走,下一个素数是3,再将所有3的倍数删去。
int prime[maxn+10];
bool vis[maxn+10];
int tot = 0;
void init(){
memset(prime,0,sizeof prime);
memset(vis,true,sizeof vis);
for(int i = 2; i <= maxn; i++){
if(vis[i]){
vis[i] = false;
prime[++tot] = i;
for(int j = i*2; j <= maxn; j += i){
vis[j] = false;
}
}
}
}
线性筛(O(N))
相对于埃氏筛法中对每个素数我们都将其倍数筛去,也就导致有许多合数我们通过其多个素数因子筛去了多次,导致时间复杂度变大,线性筛即为只通过合数最小的质因数将其筛去,也就避免了筛去多次的多余操作。
int prime[maxn+10];
bool vis[maxn+10];
int tot = 0;
void Ouler(){
memset(prime,0,sizeof prime);
memset(vis,true,sizeof vis);
for(int i = 2; i <= maxn; i++){
if(vis[i]) prime[++tot] = i;
for(int j = 1; j <= tot && i*prime[j] <= maxn; j++){
vis[i*prime[j]] = false;
if(i%prime[j] == 0) break; //关键句
}
}
}