素数筛

盗一波素数筛

const int mx = 1000000 + 1; ///在(1,mx)的范围内寻找素数 
const int sqrt_mx = (int)sqrt((double)mx); 
 
bool vis[mx]; 
int prime[mx / 10]; ///在mx>65000时建议写成 int prime[mx/10]; 
 
/*复杂度O(NloglogN)*/ 
void getPrime(int &cnt) 

    int i, j; 
    for (i = 2; i <= sqrt_mx; ++i) 
        if (!vis[i])  //不是合数
        { 
            prime[cnt++] = i; //加进
            for (j = i * i; j < mx; j += i) vis[j] = true; 
        } 
    for (; i < mx; ++i) if (!vis[i]) prime[cnt++] = i;  //对于超过一半的都是素数

 
/*复杂度O(N),但常数比较大
O(N)是因为每个合数至多被赋true值一次(每个合数n仅在i=n的最大非平凡因子(不为1和n的因子)时被赋值)
以12为例,在原来的算法中,vis[12]在i=2和i=3时均被赋值为true
而在此算法中,vis[12]只在i=6时被赋值为true(6为12的最大非平凡因子)
*/ 
void linear_getPrime(int &cnt) 

    int i, j; 
    for (i = 2; i < mx; ++i) 
    { 
        if (!vis[i]) prime[cnt++] = i; 
        for (j = 0; j < cnt && i * prime[j] < mx; ++j) 
        { 
            vis[i * prime[j]] = true; 
            if (i % prime[j] == 0) break; 
        } 
    } 

posted on 2016-05-25 17:14  very_czy  阅读(149)  评论(0编辑  收藏  举报

导航