//暴力枚举;
int isPrime(int n)
{
if(n<=1)return 0;
for(int i=2;i*i<=n;i++)
if(n%i==0)return 0;
return 1;
//每个数我们需要枚举sqrt(n)次,有n个数需要o(nsqrt(n));
}
//埃拉托斯特尼筛
memset(falg,0,sizeof(flag));
int tot=0;
for(int i=2;i<=n;i++)
{
if(!flag[i])
prime[++tot]=i;
for(int j=2*i;j<=n;j+=i)flag[j]=1;
|
//时间复杂度∑(n/i)=n*∑(1/i)就算从2枚举到n复杂度是调和的,但是现在只需要枚举质数,所以复杂度是nloglogn 所以复杂度是o(nlog(logn));
//上面的算法有些数被多个质因子访问,如15被3和5访问进行flag操作;
//算法改进后可以只被最小质因子访问;
//欧拉筛法
memset(flag,0,sizeof(flag));
int tot=0;
for(int i=2;i<=n;i++)
{
if(!flag[i])prime[++tot]=1;
for(int j=1;j<=tot&&i*prime[j]<=n;j++)
flag[i*prime[j]]=1;
if(i%prime[j]==0)break;//如果prime[j]能整除i,说明i*prime[j]已经找到最小质因子了,剩下的质 // 因子没必要找了; 举个例子
//12是被2筛掉的因为6*2=12,在判断6%2==0的时候已经知道12能被2这个质因子整除了还能被prime[i]*prime[i]整除
//我们可以想象如果i%prime[j]==0成立,那么i一定是一个合数(有因子),那么我们一定可以把i分解成a*b,
并且ab中 有一个数一定是素数.则有i*prime[j]=a*b*prime[j],我们假设a是i*prime[j]的最小素因子,
那么我们 遍历到b*prime[j]时一定能把i*prime[j]标记成合数,此时a是i*prime[j]的最小素数,所以在
遇到i的 时候我们直接跳出即可.复杂度是o(n);
}
线性筛子
最新推荐文章于 2021-06-11 11:03:29 发布