• 数论——质数筛法


    一、埃拉托斯特尼(Eratosthenes)筛法

    算法思想:

      要得到自然数n以内的全部素数,必须把不大于 的所有素数的倍数剔除,剩下的就是素数。给出要筛数值的范围n,找出以内的素数。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个质数5筛,把5留下,把5的倍数剔除掉;不断重复下去......。

    模板题链接:筛质数

    代码实现:时间复杂度O(nloglogn)

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 const int N = 10000000+10;
     6 int p[N];
     7 
     8 void prime(int n)
     9 {
    10     p[1]=1;
    11     for(int i=2;i<=n;i++)
    12     {
    13         if(p[i])continue;
    14         for(int j=2;j<=n/i;j++)p[i*j]=1;
    15     }
    16 }
    17 
    18 int main()
    19 {
    20     int n;scanf("%d",&n);
    21     prime(n);
    22     int ans=0;
    23     for(int i=1;i<=n;i++)
    24         if(!p[i])ans++;
    25     printf("%d
    ",ans);
    26     return 0;
    27 }

    二、欧拉(Euler)筛法

      欧拉筛法弥补了埃氏筛法会重复筛去合数的缺陷,而保证了每个合数只会被其最小质因子筛去且只会被筛去一次,在筛出质数的同时还得出了每个数的最小质因子,一举两得,是数论中非常常用也非常重要的一个算法。

      先上代码:时间复杂度O(n)

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 const int N = 10000000+10;
     6 
     7 int primes[N],cnt;
     8 int vis[N];
     9 
    10 void Euler_prime(int n)
    11 {
    12     for(int i=2;i<=n;i++)
    13     {
    14         if(!vis[i])primes[++cnt]=i;
    15         for(int j=1;primes[j]<=n/i;j++)
    16         {
    17             vis[primes[j]*i]=1;
    18             if(i%primes[j]==0)break;
    19         }
    20     }
    21 }
    22 
    23 int main()
    24 {
    25     int n;scanf("%d",&n);
    26     Euler_prime(n);
    27 
    28     printf("%d
    ",cnt);
    29     return 0;
    30 }

      算法理解:

      上述第18行代码保证了primes[j]一定小于等于i的所有质因子(因为如果primes[j]枚举到i的某个质因子时便会跳出枚举的循环),故primes[j]是primes[j]*i的最小质因子。

      下面证明:所有合数只会被其最小质因子筛去,且只会被筛一次。

      对于任意一个合数k,可以表示成k=p*(k/p),p是k的最小质因子。由于p≤(k/p)的所有质因子(k/p就相当于上述代码中的i),所以只有当i枚举到k/p时k才会被筛去,而枚举到其他任何数皆不会筛去k。

  • 相关阅读:
    BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第11章节--为Office和SP解决方式开发集成Apps Office新的App模型
    android Notification 的使用(锁定通知栏)
    Android中经常使用的工具类02
    【python系列】python画报表(Chartkick、Flask)(附中文乱码解决方式)
    Nginx 笔记与总结(14)expires 缓存设置
    数据分析师、数据科学家常见的77个面试问题
    数据分析师、数据科学家常见的77个面试问题
    常见数据分析方法汇总
    常见数据分析方法汇总
    机器学习、数据挖掘、人工智能、统计模型这么多概念有何差异
  • 原文地址:https://www.cnblogs.com/ninedream/p/11210339.html
Copyright © 2020-2023  润新知