线性筛法

Posted 我的露娜不会飘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性筛法相关的知识,希望对你有一定的参考价值。

【寻物启示】

我的脑子不小心被我弄丢了,有谁看见我的脑子了,请联系我,谢谢!

【线性筛法】

线性筛法是啥,它是筛法。它降低了时空复杂度,如果用暴力的方法求素数,会爆时间。

【模版】

 1 #include<cstdio>
 2 #include<cstring>
 3 #define MAXN 100005
 4 #define MAXL 1299710
 5 int prime[MAXN];//记录素数的数组 
 6 int check[MAXL]; //check:0是素数,1是合数,
 7 int tot = 0;//tot记录当前得到的素数的个数
 8 memset(check, 0, sizeof(check));
 9     for (int i = 2; i < MAXL; ++i)
10     {
11        if (!check[i])//如果它是素数 
12        {
13           prime[tot++] = i;//把它存入素数的数组 
14        }
15        for (int j = 0; j < tot; ++j)
16        {
17           if (i * prime[j] > MAXL)//当溢出时跳出循环 
18           {
19              break;
20           }
21           check[i*prime[j]] = 1;//素数的i倍都是合数 
22           if (i % prime[j] == 0)//标记完毕后,跳出循环 
23           {
24              break;
25           }
26        }
27     }

【例题--素数个数】
<题目描述>

求{1,2,...,N}中素数的个数。

<输入>

1个整数N。

<输出>

1个整数,表示素数的个数。

<样例输入>

10

<样例输出>

4

<提示>

对于40% 的数据,1 ≤ N ≤ 106;
对于80% 的数据,1 ≤ N ≤ 10 7;
对于100% 的数据,1 ≤ N <6*10 7;

【代码实现】

#include<cstdio>
#include<cstring>
#define MAXN 100005
#define MAXL 1299710
int prime[MAXN];//记录素数的数组 
int check[MAXL]; //check:0是素数,1是合数,
int tot = 0;//tot记录当前得到的素数的个数
int main()
{
    int n,sum = 0;
    scanf("%d",&n);
    memset(check, 0, sizeof(check));
    for (int i = 2; i < n; ++i)
    {
       if (!check[i])//如果它是素数 
       {
          prime[tot++] = i;//把它存入素数的数组 
       }
       for (int j = 0; j < tot; ++j)
       {
          if (i * prime[j] > n)//当溢出时跳出循环 
          {
             break;
          }
          check[i*prime[j]] = 1;//素数的i倍都是合数 
          if (i % prime[j] == 0)//标记完毕后,跳出循环 
          {
             break;
          }
       }
    }
    for(int i = 2;i <= n;i++)
    {
        if(!check[i]) sum++;
     } 
     printf("%d",sum);
     return 0;
}

【Orz】orzorzorz

以上是关于线性筛法的主要内容,如果未能解决你的问题,请参考以下文章

浅谈线性素数筛

素数筛法

线性筛法

常用积性函数的线性筛法整理

简单质数筛法-试除法,Eratosthenes筛法,线性筛法

素数的一般筛法和快速线性筛法