数论(1)
数论(1)
1.埃氏筛
素数的n倍一定不是素数,所以就打表,筛选素数。
const int maxn = 1e6+10;
bitset<maxn> isprime;
void init(int n){
isprime.set();//清空
isprime[0] = isprime[1] = 0;
int m = sqrt(maxn+0.5);
for(int i = 2;i <= m;i++){
if(isprime[i]){
for(int j = i*i;j <= m;j+=i)
isprime[j] = 0;
}
}
}
2.欧拉筛
埃氏筛有一个问题,一个数会被多次枚举
例如 18 ,它既是 2 的倍数,又是 3 的倍数,这样就被多次枚举了,这很浪费,所有就有了欧拉筛
vector<int> prime;
bitset<maxn> vis;
void euler(){
vis.reset();
for(int i = 2;i < maxn;i++){
if(!vis[i]) prime.push_back(i);
for(int j = 0;j < prime.size() && i*prime[j] < maxn;j++) {
vis[i * prime[j]] = 1; //找到质数倍
if (i % prime[j] == 0)break;
}
}
}