数论(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;  
        }  
    }  
}
posted @ 2021-01-08 13:17  Paranoid5  阅读(90)  评论(0编辑  收藏  举报