素数,又叫质数,定义是除了1和它本身以外没有别的因数
判断一个数是不是素数 复杂度O(根号N)
bool prime(int x) { if(x<=1)return false; for(LL i=2;i*i<=x;i++)if(x%i==0)return false; return true; }
求出1~N内所有的素数
埃式筛法(埃拉托斯特尼筛法)
原理:如果找到一个质数,那么这个质数的倍数都不是质数
优点:好写,稳
复杂度:O(nloglogn)
#define LL long long const int maxn=1e6+10; bool isprime[maxn]; int prime[30000]; int cnt=0; void init() { LL i,j; for(i=2;i<=maxn;i++) { if(!isprime[i]) { prime[cnt++]=i; for(j=i*i;j<=maxn;j+=i)//从i*i开始,减小被重复筛的次数 { isprime[j]=true; } } } }
但是,我们可以看出,有些合数仍然会被筛几遍,例如12,会被2筛去,又被3筛去,这样就浪费了时间
于是,我们引出
线性筛法(欧拉筛法)
复杂度:O(N)
原理:保证每一个合数都被它的最小质因子筛去
bool isprime[maxn]; int prime[maxn]; int cnt=0; void init() { int i,j; for(i=2;i<=maxn;i++) { if(!isprime[i])prime[cnt++]=i;//把质数存起来 for(j=0;j<cnt&&i*prime[j]<=maxn;j++) { isprime[i*prime[j]]=true; if(i%prime[j]==0)break;//保证每一个合数被它最小的质因数筛去 } } }