• 数论-求n以内的质数


    一、埃拉托斯特尼筛法

      名字很高大上,然而并没有什么卵用……

    思路:

      在把<=√n的质数所有的<=n的倍数剔除,剩下的就都是质数了,很容易理解……

      复杂度O(nloglogn)

     1 #include<cmath>
     2 const int MAXN=;
     3 int b[MAXN/2],top;
     4 bool a[MAXN];
     5 void cal_prime_num(int n)
     6 {
     7     k=sqrt(n);
     8     for(int i=2;i<k;i++)
     9     {
    10         if(!a[i])
    11         {
    12             int j=1;
    13             b[++top]=i;                         
    14             while(i*j<n)
    15             {
    16                    a[i*j]=true;
    17                    ++j;
    18             }
    19         }
    20      }
    21 }

    二、欧拉筛

      上一个筛法似乎复杂度不大,但是遇到107规模的数据就会炸,主要是因为一个数会被不同的质数筛好几遍,欧拉筛保证一个合数只被它的最小质因子筛去一遍,这就是整个代码最核心的部分,也是难理解的部分,然而只有一句话:

     1 if(!i%pri[j])break; 

      证明转自他人博客:

    prime数组中的素数是递增的,当 i 能整除 primej,那么 i*primej+1这个合数肯定被primej乘以某个数筛掉。
    因为i中含有primej,primej比primej+1小。接下去的素数同理。所以不用筛下去了。
    在满足i%prmej==0这个条件之前以及第一次满足改条件时,primej必定是primej*i的最小因子。

      复杂度O(n)

      其余的代码就很容易理解了:

     1 #include<cmath>
     2 const int MAXN=;
     3 int b[MAXN/2],top;
     4 bool ispri[MAXN];
     5 void cal_prime_num(int n)
     6 {
     7     for(int i=2;i<=n;++i)
     8     {
     9         if(!ispri[i])pri[++top]=i;
    10         for(int j=1;j<=top&&i*pri[j]<=n;++j)
    11         {
    12             ispri[i*pri[j]]=true;
    13             if(!i%pri[j])break;
    14         }
    15     }
    16 }
  • 相关阅读:
    过滤器--起步阶段
    常用指令-起步阶段
    模型和控制器-起步阶段
    指令介绍-起步阶段
    AngularJS简介-起步阶段
    c++之helloworld与命名空间
    c++ 之重要性
    一个没曾摸透的程序
    linux中什么是文件结构体?
    很全的linux网络编程技巧
  • 原文地址:https://www.cnblogs.com/xqmmcqs/p/6036077.html
Copyright © 2020-2023  润新知