owowowow欧拉筛可以作为一种素数筛,相比埃氏筛来讲性能更加优越
埃氏筛的时间复杂度是O(nloglogn),而欧拉筛是线性复杂度。
代码:
1 const int maxn = 1e8 + 5; 2 bool isprime[maxn]; 3 int prime[maxn], psz; 4 int n,q,x; 5 6 void getlist(){ 7 isprime[1] = true; 8 for(int i = 2; i <= n; i++){ 9 if(!isprime[i]) prime[++psz] = i; 10 for(int j = 1; j <= psz && i*prime[j] <= n; j++){ 11 isprime[i*prime[j]] = true; 12 if(i%prime[j] == 0)break; 13 } 14 } 15 }
第一层for是用i去跑一遍2到n的数字,将素数记录进prime数组,同时作为筛出素数倍数的变量
第二层for则是跑prime数组中的已经筛出的素数
而欧拉筛优于埃氏筛的原因是因为每个合数都只被其最小质因子筛去了。
if(i%prime[j] == 0)break;
当prime[j]|i时,i*prime[j+1]一定能够被prime[j]筛出(因为 i = k*prime[j],所以i*prime[j+1]会在i' = prime[j+1]*k时被prime[j]筛去
同理,因此所有的合数都将被其最小质因子筛出,保证了每个合数只会被筛选一次从而有了线性的复杂度。