两大速筛素数以及大区间素数快速统计
文中有解释:
#include<iostream> #include<cstring > #include<cstdio> #include<cmath> #define maxn 1000001 #define maxx 100005 #define mem(a,b) memset(a,b,sizeof(a)); using namespace std; int pri[maxn],book[maxn],n,cnt; int sum(int a[]) { int num=0; for(int i=2; i<=maxn; i++) if(a[i]) num++; return num; } int main() { /* 倍筛法(低能) for( int i=2; i*i<=maxn; i++) for(int j=2; j*i<=maxn; j++) prim[j]=0; */ /* 埃式筛法 */ mem(pri,1); pri[1]=0; pri[0]=0; /*如果i是素数则删除他的倍数直到大于上限 埃式筛法相对于倍筛法来说 避免了一部分重复*/ for (int i=2; i*i<maxn; i++) if(pri[i]) for(int j=i+i; j<=maxn; j+=i) pri[j]=0; cout<<sum(pri)<<endl<<endl; /* 欧拉筛法 */ mem(book,1); book[1]=0; book[0]=0; cnt=0; /*欧拉筛法*/ /*欧拉筛法的特点的是用最小 的质因数去筛除避免了质倍数的重复*/ for (int i=2; i<=maxn; i++) { if(book[i]) { pri[cnt++]=i; } for(int j=0; j<cnt&&pri[j]*i<=maxn; j++) { book[pri[j]*i]=0; if(i%pri[j]==0) break; } } cout<<sum(book)<<endl<<endl; /* 大区间筛素数(10W_1S) */ /* 据说用到了数组偏移不是很明白 就感觉像是映射一样前一部分数组对 后面的都有一个相应的影响成素数*/ while('a') { bool prim[maxx],primm[maxx]; mem(prim,1); mem(primm,1); prim[1]=0; long long f,l; cin>>f>>l; for(long long i=2; i*i<=l; i++) if(prim[i]) { for(long long j=i+i; j*j<=l; j+=i) prim[i]=0; //这里的大区间内的元素大小(f+i-1)/i //至少是i的二倍, for(int j=max(2LL,(f+i-1)/i)*i; j<=l; j+=i) primm[j-f]=0; } int ssum=0; for(int i=0; i<=l-f; i++) if(primm[i]) ssum++; if(f==1) ssum--; cout<<ssum<<endl; } return 0; }