欧拉筛法线性时间的证明

为什么欧拉筛法有两重循环却是线性的呢?

先看代码:

 1 void euler(int n){
 2     for(int i=2;i<=n;i++){
 3         if(vis[i]==0){
 4             prime[++tot]=i;
 5         }
 6         for(int j=1;j<=tot;j++){
 7             if(i*prime[j]>n){
 8                 break; 
 9             }
10             vis[i*prime[j]]=1;
11             if(i%prime[j]==0){
12                 break;
13             }
14         }
15     }
16 }


欧拉筛法有
if(i%p[j]==0)
    break;
这个语句
因为每个数都可以表示为质数的积,所以如果出现了 i%p[j]==0 的情况,那么 i 就不是 i*p[j] 的质因子,是一个合数,若将 i 表示为两个数: i 最小的质因子 a 与 i/a 的值 b 相乘 (i=a*b) ,那么 i*p[j] 也可表示为 (b*p[j])*a ,所以当前就不用筛掉 i*p[j] ,等到 i 循环到 b*p[j] 时筛掉 (b*p[j])*a 即可。
所以每个数只会被自己的最小质因子筛掉,复杂度为 O(n) 。

posted @ 2017-07-18 11:15  circlegg  阅读(1098)  评论(0编辑  收藏  举报