线性筛选素数

时间复杂度为O(n)

来自百度文库


一般的线性筛选法

prime[0] = false;

prime[1] =false;
for (int i=2;  i<N;  i++)
{
    if (prime[i])
    {
        primes[++cnt ]=i;
        for (int k=i*i; k<N; k+=i)
            prime[k]=false;
    }
}


#include<iostream>

#include <cstdio>

using namespace std;

const int n=200000;

int prime[n]= {0},num_prime=0;

int main()
{
    int a[n]= {1,1},i,j;

    for(i=2; i<10000; i++)
    {
        if(!a[i])
            prime[num_prime++]=i;
        for(j=0; j<num_prime && i*prime[j]<n; j++)
        {
        a[i*prime[j]]=1;
        if(!(i%prime[j]))
            break;
        }
    }

    /*

    for(i=0; i<100; i++)

    {
        printf("%d\n", prime[i]);
    }
    */

    return 0;

}

 
线性筛法,即是筛选掉所有合数,留下质数 
我们知道合数可以由一个质数数与另一个数相乘得到 而同时假设合数a=质数b×质数c×一个数d 令e=c × d,假设b  ≥ e,e为合数,令f=d × b  a=f × c ,其中c<e; 
即比一个合数数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到 这也是if(!( i % prime[j]))break;的含义,这也是线性筛法算质数表的关键所在


/*线性筛O(n)时间复杂度内筛出maxn内欧拉函数值*/
int  m[maxn],phi[maxn],p[maxn],pt; //m[i]是i的最小素因数,p是素数,pt是素数个数
 
int  make()
{
     phi[1]=1;
     int  N=maxn;
     int  k;
     for ( int  i=2;i<N;i++)
     {
         if (!m[i]) //i是素数
             p[pt++]=m[i]=i,phi[i]=i-1;
         for ( int  j=0;j<pt&&(k=p[j]*i)<N;j++)
         {
             m[k]=p[j];
             if (m[i]==p[j]) //为了保证以后的数不被再筛,要break
             {
                 phi[k]=phi[i]*p[j];
/*这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了*/
                 break ;    
             }
             else
                 phi[k]=phi[i]*(p[j]-1); //积性函数性质,f(i*k)=f(i)*f(k)
         }
     }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值