标签:等于 统计 max mem break 欧拉 code das size
观察如下欧拉筛代码:
1 const int MAXN=30000001; 2 int prime[MAXN]; 3 bool vis[MAXN]; 4 int Prime(int n){ 5 int cnt=0; 6 memset(vis,0,sizeof(vis)); 7 for(int i=2;i<n;i++){ 8 if(!vis[i]) 9 prime[cnt++]=i; 10 for(int j=0;j<cnt&&i*prime[j]<n;j++){ 11 vis[i*prime[j]]=1; 12 if(i%prime[j]==0) 13 break; 14 } 15 } 16 return cnt; 17 }
发现其流程如下:
充分性:
——为什么流程第2行是正确的呢?
任意合数k可表示为其 最小质因子pj 与 数i 相乘(i:质数or合数)
且pj小于等于 数i 的最小质因子(否则该质因子才是k的最小质因子)
所以只要数i被枚举,合数k即被筛除(见流程3,4行)
由于i一定小于k,故当枚举到合数k时,她已经被删除啦(见流程1行)
即,该流程满足使所有合数被数i与该合数最小质因子pj相乘的情况筛去
效率:
——为什么这样快?
在流程中,统计筛操作的次数:
由于合数k只被数i与该合数最小质因子pj相乘的情况筛去
(当另一个数l想要与k的另一个大点的质因子pm筛去k时,她惊奇地发现她的最小质因子比pm大——因为pj正是她的最小质因子——这就意味着她不能筛k)
所以所以合数只被筛了一次;
视为O(n)的效率
附上一个筛数的流程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
枚举至2,并筛除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
质数:2;
枚举至3,并筛除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
质数:2,3;
枚举至4,并筛除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
质数:2,3;
枚举至5,并筛除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
质数:2,3,5;
枚举至6,并筛除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
质数:2,3,5;
枚举至7,并筛除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
质数:2,3,5,7;
然后重复以上过程,筛除,并记录质数;
(由于最小质数2,与8相乘已经大与15,故该筛的早已筛了,现在主要是记录质数,但流程还得继续啊)
标签:等于 统计 max mem break 欧拉 code das size
原文地址:http://www.cnblogs.com/nietzsche-oier/p/6595627.html