欧拉筛法线性时间的证明
为什么欧拉筛法有两重循环却是线性的呢?
先看代码:
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) 。