zoukankan      html  css  js  c++  java
  • 线性筛

    线性筛:在(Oleft ( n ight ))时间复杂度内筛出某东西

    任意积性函数都可以线性筛

    下面以线性筛素数说明为什么是线性的:

     1 void make_prime()
     2 {
     3     memset(prime,true,sizeof(prime));
     4     prime[0]=prime[1]=false;
     5     for(register int i=2; i<=maxn; i++)
     6     {
     7         if( prime[i]) Prime[num++]=i;
     8         for(register int j=0; j<num&&i*Prime[j]<maxn; j++)
     9         {
    10             prime[i*Prime[j]] = false;
    11             if( !(i%Prime[j]) ) break;
    12         }
    13     }
    14     return ;
    15 }

    分析(核心):算法的关键之处在于break语句,break是为了保证任何一个合数都是被它的最小质因子筛掉的,所以能够保证每个数都自会被访问一次,这也就保证了复杂度是线性的

    解释:根据唯一分解定理:任意一个数(n)都可以分解成:(n=p_{1}^{t_{1}}p_{2}^{t_{2}}p_{3}^{t_{3}}cdots p_{k}^{t_{k}})

    所以我们要筛掉(n)的话,肯定是用 (p_{1})去筛。

    如果出现了 (left ( i mod Primeleft [ j ight ] ight )==0)  则说明  (Primeleft [ j ight ]是i的质因子) ,那么此时如果我们继续用  (i*Primeleft [ j+1 ight ])  去筛某个数 (x) 的话,我们就是用  (Primeleft [ j+1 ight ])  去筛的 (x),可是很显然  (Primeleft [ j ight ])  是(x)的一个质因子,并且  (Primeleft [ j ight ])  比  (Primeleft [ j+1 ight ])  小,所以  (Primeleft [ j+1 ight ])  不是 (x) 的最小质因子,于是break,也就保证了每个数是被它的最小质因子筛掉的。

  • 相关阅读:
    2012年8月20日 我单身了!
    IE8与VS2008 添加变量 脚本错误的解决方案
    感染导入表方法附源码(转载)
    获取远程网卡MAC地址(VC++)
    [转]VC 中 TreeView 全面解析
    利用INF安装服务启动
    IOCP编程之基本原理
    LIMIT 用法
    SQL Server 触发器的删除操作
    CLRviaCsharp学习笔记
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12777817.html
Copyright © 2011-2022 走看看